More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 32,368 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mint | 29284315 | 11 hrs ago | IN | 0.00005 ETH | 0.00000041 | ||||
Mint | 29284195 | 11 hrs ago | IN | 0.00005 ETH | 0.0000004 | ||||
Set Approval For... | 29280675 | 13 hrs ago | IN | 0 ETH | 0.00000005 | ||||
Send From | 29232648 | 39 hrs ago | IN | 0.0000802 ETH | 0.00000105 | ||||
Mint | 29232630 | 40 hrs ago | IN | 0.00005 ETH | 0.00000062 | ||||
Mint | 29232491 | 40 hrs ago | IN | 0.00005 ETH | 0.00000068 | ||||
Send From | 29094934 | 4 days ago | IN | 0.00015186 ETH | 0.00000061 | ||||
Mint | 29094924 | 4 days ago | IN | 0.00005 ETH | 0.00000035 | ||||
Send From | 29089347 | 4 days ago | IN | 0.00015013 ETH | 0.00000068 | ||||
Mint | 29089313 | 4 days ago | IN | 0.00005 ETH | 0.00000033 | ||||
Send From | 29059818 | 5 days ago | IN | 0.00008932 ETH | 0.00000124 | ||||
Send From | 29057676 | 5 days ago | IN | 0.00029527 ETH | 0.00000079 | ||||
Mint | 29057645 | 5 days ago | IN | 0.00005 ETH | 0.00000047 | ||||
Send From | 29042662 | 6 days ago | IN | 0.00015186 ETH | 0.00000276 | ||||
Mint | 29042651 | 6 days ago | IN | 0.00005 ETH | 0.00000158 | ||||
Mint | 29014855 | 6 days ago | IN | 0.00005 ETH | 0.0000004 | ||||
Send From | 29014830 | 6 days ago | IN | 0.00015186 ETH | 0.00000066 | ||||
Mint | 29014817 | 6 days ago | IN | 0.00005 ETH | 0.0000004 | ||||
Send From | 29014800 | 6 days ago | IN | 0.00015186 ETH | 0.00000066 | ||||
Mint | 29014791 | 6 days ago | IN | 0.00005 ETH | 0.00000047 | ||||
Send From | 28985674 | 7 days ago | IN | 0.00013944 ETH | 0.00000055 | ||||
Send From | 28929436 | 8 days ago | IN | 0.00008762 ETH | 0.00000162 | ||||
Send From | 28903649 | 9 days ago | IN | 0.00007877 ETH | 0.00000059 | ||||
Send From | 28903620 | 9 days ago | IN | 0.00008932 ETH | 0.00000058 | ||||
Mint | 28903599 | 9 days ago | IN | 0.00005 ETH | 0.00000034 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
29232648 | 39 hrs ago | 0.0000202 ETH | ||||
29094934 | 4 days ago | 0.00009186 ETH | ||||
29089347 | 4 days ago | 0.00009013 ETH | ||||
29059818 | 5 days ago | 0.00002932 ETH | ||||
29057676 | 5 days ago | 0.00023527 ETH | ||||
29042662 | 6 days ago | 0.00009186 ETH | ||||
29014830 | 6 days ago | 0.00009186 ETH | ||||
29014800 | 6 days ago | 0.00009186 ETH | ||||
28985674 | 7 days ago | 0.00007944 ETH | ||||
28929436 | 8 days ago | 0.00002762 ETH | ||||
28903649 | 9 days ago | 0.00001877 ETH | ||||
28903620 | 9 days ago | 0.00002932 ETH | ||||
28902789 | 9 days ago | 0.00002762 ETH | ||||
28882759 | 9 days ago | 0.00001877 ETH | ||||
28879221 | 9 days ago | 0.00009186 ETH | ||||
28875199 | 9 days ago | 0.00002932 ETH | ||||
28843569 | 10 days ago | 0.0000896 ETH | ||||
28829723 | 10 days ago | 0.00009632 ETH | ||||
28829552 | 10 days ago | 0.00009632 ETH | ||||
28829443 | 10 days ago | 0.0002112 ETH | ||||
28829289 | 11 days ago | 0.00003115 ETH | ||||
28829239 | 11 days ago | 0.00009632 ETH | ||||
28829167 | 11 days ago | 0.00009632 ETH | ||||
28800822 | 11 days ago | 0.00003115 ETH | ||||
28762845 | 12 days ago | 0.00009632 ETH |
Loading...
Loading
Contract Name:
GetMintONFT721
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at basescan.org on 2024-06-08 */ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.13; // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @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); event SetMinGasToTransferAndStore(uint256 _minGasToTransferAndStore); event SetDstChainIdToTransferGas(uint16 _dstChainId, uint256 _dstChainIdToTransferGas); event SetDstChainIdToBatchLimit(uint16 _dstChainId, uint256 _dstChainIdToBatchLimit); /** * @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); } // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } /** * @dev Interface of the ONFT standard */ interface IONFT721 is IONFT721Core, IERC721 { } // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } 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; } 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; } 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); } /* * @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. */ 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; } } /* * 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 _remoteChainId, bytes calldata _path) external onlyOwner { trustedRemoteLookup[_remoteChainId] = _path; emit SetTrustedRemote(_remoteChainId, _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); } } 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) } } } /* * 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); } } // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } abstract contract ONFT721Core is NonblockingLzApp, ERC165, ReentrancyGuard, 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, "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, "tokenIds[] is empty"); require(_tokenIds.length == 1 || _tokenIds.length <= dstChainIdToBatchLimit[_dstChainId], "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 virtual nonReentrant { bytes32 hashedPayload = keccak256(_payload); require(storedCredits[hashedPayload].creditsRemain, "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, "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, "minGasToTransferAndStore must be > 0"); minGasToTransferAndStore = _minGasToTransferAndStore; emit SetMinGasToTransferAndStore(_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, "dstChainIdToTransferGas must be > 0"); dstChainIdToTransferGas[_dstChainId] = _dstChainIdToTransferGas; emit SetDstChainIdToTransferGas(_dstChainId, _dstChainIdToTransferGas); } // limit on src the amount of tokens to batch send function setDstChainIdToBatchLimit(uint16 _dstChainId, uint256 _dstChainIdToBatchLimit) external onlyOwner { require(_dstChainIdToBatchLimit > 0, "dstChainIdToBatchLimit must be > 0"); dstChainIdToBatchLimit[_dstChainId] = _dstChainIdToBatchLimit; emit SetDstChainIdToBatchLimit(_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; } } // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } /** * @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 = _ownerOf(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 or 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 or 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 or 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @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 _ownerOf(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, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @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, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @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. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } } // NOTE: this ONFT contract has no public minting logic. // must implement your own minting logic in child classes contract ONFT721 is ONFT721Core, ERC721, IONFT721 { 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) 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); } } } // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } /** * @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 See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; 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(); } } /** * @author GetMint * @title GetMintONFT721 */ contract GetMintONFT721 is ONFT721, ERC721Enumerable { /************ * ERRORS * ************/ /** * @notice Contract error codes, used to specify the error * CODE LIST: * E1 "Invalid token URI lock state" * E2 "Mint exceeds the limit" * E3 "Invalid mint fee" * E4 "Invalid token ID" * E5 "Invalid fee collector address" * E6 "Invalid earned fee amount: nothing to claim" * E7 "Caller is not a fee collector" * E8 "Invalid referral bips: value is too high" * E9 "Invalid referer address" */ uint8 public constant ERROR_INVALID_URI_LOCK_STATE = 1; uint8 public constant ERROR_MINT_EXCEEDS_LIMIT = 2; uint8 public constant ERROR_MINT_INVALID_FEE = 3; uint8 public constant ERROR_INVALID_TOKEN_ID = 4; uint8 public constant ERROR_INVALID_COLLECTOR_ADDRESS = 5; uint8 public constant ERROR_NOTHING_TO_CLAIM = 6; uint8 public constant ERROR_NOT_FEE_COLLECTOR = 7; uint8 public constant ERROR_REFERRAL_BIPS_TOO_HIGH = 8; uint8 public constant ERROR_INVALID_REFERER = 9; /** * @notice Basic error, thrown every time something goes wrong according to the contract logic. * @dev The error code indicates more details. */ error GetMintONFT721_CoreError(uint256 errorCode); /************ * EVENTS * ************/ /** * State change */ event MintFeeChanged(uint256 indexed oldMintFee, uint256 indexed newMintFee); event BridgeFeeChanged(uint256 indexed oldBridgeFee, uint256 indexed newBridgeFee); event ReferralEarningBipsChanged(uint256 indexed oldReferralEarningBips, uint256 indexed newReferralEarningBips); event EarningBipsForReferrerChanged(address indexed referrer, uint256 newEraningBips); event EarningBipsForReferrersChanged(address[] indexed referrers, uint256 newEraningBips); event FeeCollectorChanged(address indexed oldFeeCollector, address indexed newFeeCollector); event TokenURIChanged(string indexed oldTokenURI, string indexed newTokenURI, string fileExtension); event TokenURILocked(bool indexed newState); /** * Mint / bridge / claim */ event ONFTMinted( address indexed minter, uint256 indexed itemId, uint256 feeEarnings, address indexed referrer, uint256 referrerEarnings ); event BridgeFeeEarned( address indexed from, uint16 indexed dstChainId, uint256 amount ); event FeeEarningsClaimed(address indexed collector, uint256 claimedAmount); event ReferrerEarningsClaimed(address indexed referrer, uint256 claimedAmount); /*************** * CONSTANTS * ***************/ uint256 public constant ONE_HUNDRED_PERCENT = 10000; // 100% uint256 public constant FIFTY_PERCENT = 5000; // 50% uint256 public constant DENOMINATOR = ONE_HUNDRED_PERCENT; // 100% /*********************** * VARIABLES / STATES * ***********************/ /// TOKEN ID /// uint256 public immutable startMintId; uint256 public immutable maxMintId; uint256 public tokenCounter; /// FEE /// uint256 public mintFee; uint256 public bridgeFee; address public feeCollector; uint256 public feeEarnedAmount; uint256 public feeClaimedAmount; /// REFERRAL FEE /// uint256 public referralEarningBips; mapping (address => uint256) public referrersEarningBips; mapping (address => uint256) public referredTransactionsCount; mapping (address => uint256) public referrersEarnedAmount; mapping (address => uint256) public referrersClaimedAmount; /// TOKEN URI /// string private _tokenURIExtension; string private _tokenBaseURI; bool public tokenBaseURILocked; /*************** * MODIFIERS * ***************/ /** * @dev Protects functions available only to the fee collector, e.g. fee claiming */ modifier onlyFeeCollector() { _checkFeeCollector(); _; } /***************** * CONSTRUCTOR * *****************/ /** * @param _minGasToTransfer min amount of gas required to transfer, and also store the payload. See {ONFT721Core} * @param _lzEndpoint LayerZero endpoint address * @param _startMintId min token ID that can be mined * @param _endMintId max token ID that can be mined * @param _mintFee fee amount to be sent as message value when calling the mint function * @param _bridgeFee fee amount to be sent as part of the value message when calling the mint function * @param _feeCollector the address to which the fee claiming is authorized */ constructor( uint256 _minGasToTransfer, address _lzEndpoint, uint256 _startMintId, uint256 _endMintId, uint256 _mintFee, uint256 _bridgeFee, address _feeCollector, uint256 _referralEarningBips ) ONFT721("GetMintONFT", "GTM", _minGasToTransfer, _lzEndpoint) { require(_startMintId < _endMintId, "Invalid mint range"); require(_endMintId < type(uint256).max, "Incorrect max mint ID"); require(_feeCollector != address(0), "Invalid fee collector address"); require(_referralEarningBips <= FIFTY_PERCENT, "Invalid referral earning shares"); startMintId = _startMintId; maxMintId = _endMintId; mintFee = _mintFee; bridgeFee = _bridgeFee; feeCollector = _feeCollector; referralEarningBips = _referralEarningBips; tokenCounter = _startMintId; } /*********************** * SETTERS / GETTERS * ***********************/ /** * @notice ADMIN Change minting fee * @param _mintFee new minting fee * * @dev emits {GetMintONFT721-MintFeeChanged} */ function setMintFee(uint256 _mintFee) external onlyOwner { uint256 oldMintFee = mintFee; mintFee = _mintFee; emit MintFeeChanged(oldMintFee, _mintFee); } /** * @notice ADMIN Change bridge fee * @param _bridgeFee new bridge fee * * @dev emits {GetMintONFT721-BridgeFeeChanged} */ function setBridgeFee(uint256 _bridgeFee) external onlyOwner { uint256 oldBridgeFee = bridgeFee; bridgeFee = _bridgeFee; emit BridgeFeeChanged(oldBridgeFee, _bridgeFee); } /** * @notice ADMIN Change referral earning share * @param _referralEarninBips new referral earning share * * @dev emits {GetMintONFT721-ReferralEarningBipsChanged} */ function setReferralEarningBips(uint256 _referralEarninBips) external onlyOwner { _validate(_referralEarninBips <= FIFTY_PERCENT, ERROR_REFERRAL_BIPS_TOO_HIGH); uint256 oldReferralEarningsShareBips = referralEarningBips; referralEarningBips = _referralEarninBips; emit ReferralEarningBipsChanged(oldReferralEarningsShareBips, _referralEarninBips); } /** * @notice ADMIN Change referral earning share for specific referrer * @param referrer address for which a special share is set * @param earningBips new referral earning share for referrer * * @dev emits {GetMintONFT721-EarningBipsForReferrerChanged} */ function setEarningBipsForReferrer( address referrer, uint256 earningBips ) external onlyOwner { _validate(earningBips <= ONE_HUNDRED_PERCENT, ERROR_REFERRAL_BIPS_TOO_HIGH); referrersEarningBips[referrer] = earningBips; emit EarningBipsForReferrerChanged(referrer, earningBips); } /** * @notice ADMIN Change referral earning share for specific referrers * @param referrers addresses for which a special share is set * @param earningBips new referral earning share for referrers * * @dev emits {GetMintONFT721-EarningBipsForReferrersChanged} */ function setEarningBipsForReferrersBatch( address[] calldata referrers, uint256 earningBips ) external onlyOwner { _validate(earningBips <= ONE_HUNDRED_PERCENT, ERROR_REFERRAL_BIPS_TOO_HIGH); for (uint256 i; i < referrers.length; i++) { referrersEarningBips[referrers[i]] = earningBips; } emit EarningBipsForReferrersChanged(referrers, earningBips); } /** * @notice ADMIN Change fee collector address * @param _feeCollector new address for the collector * * @dev emits {GetMintONFT721-FeeCollectorChanged} */ function setFeeCollector(address _feeCollector) external onlyOwner { _validate(_feeCollector != address(0), ERROR_INVALID_COLLECTOR_ADDRESS); address oldFeeCollector = feeCollector; feeCollector = _feeCollector; emit FeeCollectorChanged(oldFeeCollector, _feeCollector); } /** * @notice ADMIN Change base URI * @param _newTokenBaseURI new URI * @param _fileExtension file extension in format ".<ext>" * * @dev emits {GetMintONFT721-TokenURIChanged} */ function setTokenBaseURI( string calldata _newTokenBaseURI, string calldata _fileExtension ) external onlyOwner { _validate(!tokenBaseURILocked, ERROR_INVALID_URI_LOCK_STATE); string memory oldTokenBaseURI = _tokenBaseURI; _tokenBaseURI = _newTokenBaseURI; _tokenURIExtension = _fileExtension; emit TokenURIChanged(oldTokenBaseURI, _newTokenBaseURI, _fileExtension); } /** * @notice ADMIN Lock / unlock base URI * @param locked lock token URI if true, unlock otherwise * * @dev emits {GetMintONFT721-TokenURILocked} */ function setTokenBaseURILocked(bool locked) external onlyOwner { _validate(tokenBaseURILocked != locked, ERROR_INVALID_URI_LOCK_STATE); tokenBaseURILocked = locked; emit TokenURILocked(locked); } /** * @notice Retrieving token URI by its ID * @param tokenId identifier of the token * * @dev emits {GetMintONFT721-TokenURILocked} */ function tokenURI(uint256 tokenId) public view override returns (string memory) { _validate(_exists(tokenId), ERROR_INVALID_TOKEN_ID); return string(abi.encodePacked(_tokenBaseURI, Strings.toString(tokenId), _tokenURIExtension)); } /************ * MINT * ************/ /** * @notice Mint new GetMint ONFT * * @dev new token ID must be in range [startMintId - maxMintId] * @dev tx value must be equal to mintFee. See {GetMintONFT721-mintFee} * @dev emits {GetMintONFT721-ONFTMinted} */ function mint() external payable nonReentrant { uint256 newItemId = tokenCounter; uint256 feeEarnings = mintFee; _validate(newItemId < maxMintId, ERROR_MINT_EXCEEDS_LIMIT); _validate(msg.value >= feeEarnings, ERROR_MINT_INVALID_FEE); ++tokenCounter; feeEarnedAmount += feeEarnings; _safeMint(_msgSender(), newItemId); emit ONFTMinted( _msgSender(), newItemId, feeEarnings, address(0), 0 ); } /** * @notice Mint new GetMint ONFT by referral * @param referrer referral address * * @dev new token ID must be in range [startMintId - maxMintId] * @dev tx value must be equal to mintFee. See {GetMintONFT721-mintFee} * @dev referrer address must be non-zero * @dev emits {GetMintONFT721-ONFTMinted} */ function mint(address referrer) public payable nonReentrant { uint256 newItemId = tokenCounter; uint256 _mintFee = mintFee; _validate(newItemId < maxMintId, ERROR_MINT_EXCEEDS_LIMIT); _validate(msg.value >= _mintFee, ERROR_MINT_INVALID_FEE); _validate(referrer != _msgSender() && referrer != address(0), ERROR_INVALID_REFERER); ++tokenCounter; uint256 referrerBips = referrersEarningBips[referrer]; uint256 referrerShareBips = referrerBips == 0 ? referralEarningBips : referrerBips; uint256 referrerEarnings = (_mintFee * referrerShareBips) / DENOMINATOR; uint256 feeEarnings = _mintFee - referrerEarnings; referrersEarnedAmount[referrer] += referrerEarnings; ++referredTransactionsCount[referrer]; feeEarnedAmount += feeEarnings; _safeMint(_msgSender(), newItemId); emit ONFTMinted( _msgSender(), newItemId, feeEarnings, referrer, referrerEarnings ); } /************** * BRIDGE * **************/ /** * @notice Estimate fee to send token to another chain * @param _dstChainId destination LayerZero chain ID * @param _toAddress address on destination * @param _tokenId token to be sent * @param _useZro flag to use ZRO as fee * @param _adapterParams relayer adapter parameters * * @dev See {ONFT721Core-estimateSendFee} * @dev Overridden to add bridgeFee to native fee */ function estimateSendFee( uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, bool _useZro, bytes memory _adapterParams ) public view virtual override(ONFT721Core, IONFT721Core) returns (uint nativeFee, uint zroFee) { return this.estimateSendBatchFee( _dstChainId, _toAddress, _toSingletonArray(_tokenId), _useZro, _adapterParams ); } /** * @notice Estimate fee to send batch of tokens to another chain * @param _dstChainId destination LayerZero chain ID * @param _toAddress address on destination * @param _tokenIds tokens to be sent * @param _useZro flag to use ZRO as fee * @param _adapterParams relayer adapter parameters * * @dev See {ONFT721Core-estimateSendBatchFee} * @dev Overridden to add bridgeFee to native fee */ function estimateSendBatchFee( uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, bool _useZro, bytes memory _adapterParams ) public view override(ONFT721Core, IONFT721Core) returns (uint256 nativeFee, uint256 zroFee) { (nativeFee, zroFee) = super.estimateSendBatchFee( _dstChainId, _toAddress, _tokenIds, _useZro, _adapterParams ); nativeFee += bridgeFee; return (nativeFee, zroFee); } /** * @notice Send token to another chain * @param _from sender address, token owner or approved address * @param _dstChainId destination LayerZero chain ID * @param _toAddress address on destination * @param _tokenId token to be sent * @param _refundAddress address that would receive remaining funds * @param _zroPaymentAddress address that would pay fees in zro * @param _adapterParams relayer adapter parameters * * @dev See {ONFT721Core-sendFrom} * @dev Overridden to collect bridgeFee */ function sendFrom( address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams ) public payable override(ONFT721Core, IONFT721Core) { _handleSend( _from, _dstChainId, _toAddress, _toSingletonArray(_tokenId), _refundAddress, _zroPaymentAddress, _adapterParams ); } /** * @notice Send token to another chain * @param _from sender address, token owner or approved address * @param _dstChainId destination LayerZero chain ID * @param _toAddress address on destination * @param _tokenIds tokens to be sent * @param _refundAddress address that would receive remaining funds * @param _zroPaymentAddress address that would pay fees in zro * @param _adapterParams relayer adapter parameters * * @dev See {ONFT721Core-sendBatchFrom} * @dev Overridden to collect bridgeFee */ function sendBatchFrom( address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams ) public payable virtual override(ONFT721Core, IONFT721Core) { _handleSend( _from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams ); } /** * @notice Internal function to handle send to another chain * @param _from sender address, token owner or approved address * @param _dstChainId destination LayerZero chain ID * @param _toAddress address on destination * @param _tokenIds tokens to be sent * @param _refundAddress address that would receive remaining funds * @param _zroPaymentAddress address that would pay fees in zro * @param _adapterParams relayer adapter parameters * * @dev emits {GetMintONFT721-BridgeFeeEarned} */ function _handleSend( address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams ) private { uint256 _bridgeFee = bridgeFee; uint256 _nativeFee = msg.value - _bridgeFee; feeEarnedAmount += _bridgeFee; _send( _from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams, _nativeFee ); emit BridgeFeeEarned(_from, _dstChainId, _bridgeFee); } /** * @notice Internal function to handle send to another chain * @param _from sender address, token owner or approved address * @param _dstChainId destination LayerZero chain ID * @param _toAddress address on destination * @param _tokenIds tokens to be sent * @param _refundAddress address that would receive remaining funds * @param _zroPaymentAddress address that would pay fees in zro * @param _adapterParams relayer adapter parameters * @param _nativeFee fee amount to be sent to LayerZero (without bridgeFee) * * @dev Mimics the behavior of {ONFT721Core} * @dev emits {IONFT721Core-SendToChain} */ function _send( address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, uint256 _nativeFee ) internal virtual { // allow 1 by default require(_tokenIds.length > 0, "tokenIds[] is empty"); require( _tokenIds.length == 1 || _tokenIds.length <= dstChainIdToBatchLimit[_dstChainId], "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, _nativeFee ); emit SendToChain(_dstChainId, _from, _toAddress, _tokenIds); } /************* * CLAIM * *************/ /** * @notice FEE_COLLECTOR Claim earned fee (mint + bridge) * * @dev earned amount must be more than zero to claim * @dev emits {GetMintONFT721-FeeEarningsClaimed} */ function claimFeeEarnings() external onlyFeeCollector nonReentrant { uint256 _feeEarnedAmount = feeEarnedAmount; _validate(_feeEarnedAmount != 0, ERROR_NOTHING_TO_CLAIM); uint256 currentEarnings = _feeEarnedAmount; feeEarnedAmount = 0; feeClaimedAmount += currentEarnings; address _feeCollector = feeCollector; (bool success, ) = payable(_feeCollector).call{value: currentEarnings}(""); require(success, "Failed to send Ether"); emit FeeEarningsClaimed(_feeCollector, currentEarnings); } /** * @notice Claim earned fee from referral mint * * @dev earned amount must be more than zero to claim * @dev emits {GetMintONFT721-ReferrerEarningsClaimed} */ function claimReferrerEarnings() external { uint256 earnings = referrersEarnedAmount[_msgSender()]; _validate(earnings != 0, ERROR_NOTHING_TO_CLAIM); referrersEarnedAmount[_msgSender()] = 0; referrersClaimedAmount[_msgSender()] += earnings; (bool sent, ) = payable(_msgSender()).call{value: earnings}(""); require(sent, "Failed to send Ether"); emit ReferrerEarningsClaimed(_msgSender(), earnings); } /***************** * OVERRIDES * *****************/ /** * @dev See {ERC721-_beforeTokenTransfer} */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); } /** * @dev See {ERC721-supportsInterface} */ function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC721Enumerable, ONFT721) returns (bool) { return interfaceId == type(IONFT721).interfaceId || super.supportsInterface(interfaceId); } /*************** * HELPERS * ***************/ /** * @notice Checks if address is current fee collector */ function _checkFeeCollector() internal view { _validate(feeCollector == _msgSender(), ERROR_NOT_FEE_COLLECTOR); } /** * @notice Checks if the condition is met and reverts with an error if not * @param _clause condition to be checked * @param _errorCode code that will be passed in the error */ function _validate(bool _clause, uint8 _errorCode) internal pure { if (!_clause) revert GetMintONFT721_CoreError(_errorCode); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"_minGasToTransfer","type":"uint256"},{"internalType":"address","name":"_lzEndpoint","type":"address"},{"internalType":"uint256","name":"_startMintId","type":"uint256"},{"internalType":"uint256","name":"_endMintId","type":"uint256"},{"internalType":"uint256","name":"_mintFee","type":"uint256"},{"internalType":"uint256","name":"_bridgeFee","type":"uint256"},{"internalType":"address","name":"_feeCollector","type":"address"},{"internalType":"uint256","name":"_referralEarningBips","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"errorCode","type":"uint256"}],"name":"GetMintONFT721_CoreError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"oldBridgeFee","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newBridgeFee","type":"uint256"}],"name":"BridgeFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint16","name":"dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BridgeFeeEarned","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":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"newEraningBips","type":"uint256"}],"name":"EarningBipsForReferrerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address[]","name":"referrers","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"newEraningBips","type":"uint256"}],"name":"EarningBipsForReferrersChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldFeeCollector","type":"address"},{"indexed":true,"internalType":"address","name":"newFeeCollector","type":"address"}],"name":"FeeCollectorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collector","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimedAmount","type":"uint256"}],"name":"FeeEarningsClaimed","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":"uint256","name":"oldMintFee","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newMintFee","type":"uint256"}],"name":"MintFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"uint256","name":"itemId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeEarnings","type":"uint256"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"referrerEarnings","type":"uint256"}],"name":"ONFTMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"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":true,"internalType":"uint256","name":"oldReferralEarningBips","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"newReferralEarningBips","type":"uint256"}],"name":"ReferralEarningBipsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimedAmount","type":"uint256"}],"name":"ReferrerEarningsClaimed","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":"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":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"SetDstChainIdToBatchLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"}],"name":"SetDstChainIdToTransferGas","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":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"SetMinGasToTransferAndStore","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":"string","name":"oldTokenURI","type":"string"},{"indexed":true,"internalType":"string","name":"newTokenURI","type":"string"},{"indexed":false,"internalType":"string","name":"fileExtension","type":"string"}],"name":"TokenURIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"newState","type":"bool"}],"name":"TokenURILocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_PAYLOAD_SIZE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_INVALID_COLLECTOR_ADDRESS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_INVALID_REFERER","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_INVALID_TOKEN_ID","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_INVALID_URI_LOCK_STATE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_MINT_EXCEEDS_LIMIT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_MINT_INVALID_FEE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_NOTHING_TO_CLAIM","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_NOT_FEE_COLLECTOR","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_REFERRAL_BIPS_TOO_HIGH","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FIFTY_PERCENT","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":[],"name":"ONE_HUNDRED_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"bridgeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimFeeEarnings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimReferrerEarnings","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":[],"name":"feeClaimedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeEarnedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uint16","name":"_remoteChainId","type":"uint16"}],"name":"getTrustedRemoteAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"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":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"referrer","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[{"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":"referralEarningBips","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"referredTransactionsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"referrersClaimedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"referrersEarnedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"referrersEarningBips","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"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":"uint256","name":"_bridgeFee","type":"uint256"}],"name":"setBridgeFee","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":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"earningBips","type":"uint256"}],"name":"setEarningBipsForReferrer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"referrers","type":"address[]"},{"internalType":"uint256","name":"earningBips","type":"uint256"}],"name":"setEarningBipsForReferrersBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeCollector","type":"address"}],"name":"setFeeCollector","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":"uint256","name":"_mintFee","type":"uint256"}],"name":"setMintFee","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":"uint256","name":"_referralEarninBips","type":"uint256"}],"name":"setReferralEarningBips","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newTokenBaseURI","type":"string"},{"internalType":"string","name":"_fileExtension","type":"string"}],"name":"setTokenBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"locked","type":"bool"}],"name":"setTokenBaseURILocked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","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":[],"name":"startMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"tokenBaseURILocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenCounter","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"}]
Contract Creation Code
60e06040523480156200001157600080fd5b506040516200633338038062006333833981016040819052620000349162000327565b6040518060400160405280600b81526020016a11d95d135a5b9d13d3919560aa1b8152506040518060400160405280600381526020016247544d60e81b81525089898383838380806200009662000090620002b660201b60201c565b620002ba565b6001600160a01b031660805250600160065581620001075760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b60648201526084015b60405180910390fd5b50600755600b6200011983826200043e565b50600c6200012882826200043e565b50505050505050848610620001755760405162461bcd60e51b8152602060048201526012602482015271496e76616c6964206d696e742072616e676560701b6044820152606401620000fe565b6000198510620001c85760405162461bcd60e51b815260206004820152601560248201527f496e636f7272656374206d6178206d696e7420494400000000000000000000006044820152606401620000fe565b6001600160a01b038216620002205760405162461bcd60e51b815260206004820152601d60248201527f496e76616c69642066656520636f6c6c6563746f7220616464726573730000006044820152606401620000fe565b611388811115620002745760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420726566657272616c206561726e696e6720736861726573006044820152606401620000fe565b60a086905260c094909452601692909255601755601880546001600160a01b0319166001600160a01b03909216919091179055601b55601555506200050a9050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200032257600080fd5b919050565b600080600080600080600080610100898b0312156200034557600080fd5b885197506200035760208a016200030a565b965060408901519550606089015194506080890151935060a089015192506200038360c08a016200030a565b915060e089015190509295985092959890939650565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620003c457607f821691505b602082108103620003e557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200043957600081815260208120601f850160051c81016020861015620004145750805b601f850160051c820191505b81811015620004355782815560010162000420565b5050505b505050565b81516001600160401b038111156200045a576200045a62000399565b62000472816200046b8454620003af565b84620003eb565b602080601f831160018114620004aa5760008415620004915750858301515b600019600386901b1c1916600185901b17855562000435565b600085815260208120601f198616915b82811015620004db57888601518255948401946001909101908401620004ba565b5085821015620004fa5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c051615db36200058060003960008181610f52015281816117b70152611f7001526000610858015260008181610d3b015281816110ce015281816114e90152818161176d01528181611bf401528181612a4c0152818161300f01528181613abd01526146b20152615db36000f3fe6080604052600436106104f65760003560e01c80638da5cb5b1161028c578063c74046f91161015a578063e0381d7d116100cc578063eb8d72b711610085578063eb8d72b714610ffe578063eddd0d9c1461101e578063f23536411461103e578063f2fde38b1461105e578063f5ecbdbc1461107e578063fa25f9b61461109e57600080fd5b8063e0381d7d14610f2a578063e1d4c87014610f40578063e985e9c514610f74578063e9c9637914610fbd578063ea0d9e1814610fd2578063eb56c48514610fe857600080fd5b8063d082e3811161011e578063d082e38114610ea1578063d12473a514610eb7578063d1deba1f14610ed7578063dd0081c714610bce578063df2a5b3b14610eea578063df329fc114610f0a57600080fd5b8063c74046f914610dff578063c87b56dd14610e14578063cbc1418a14610e34578063cbed8b9c14610e54578063cf836dc314610e7457600080fd5b8063a22cb465116101fe578063b88d4fde116101b7578063b88d4fde14610d5d578063baf3292d14610d7d578063c2690cb614610d9d578063c415b95c14610dca578063c446183414610bce578063c6f0995614610dea57600080fd5b8063a22cb46514610c8e578063a42dce8014610cae578063a6c3d16514610cce578063ab3ffb9314610cee578063af3fb21c14610d01578063b353aaa714610d2957600080fd5b8063950c8a7411610250578063950c8a7414610be457806395d89b4114610c04578063998cdf8314610c195780639ae0088314610c395780639ea5d6b114610c4e5780639f38369a14610c6e57600080fd5b80638da5cb5b14610b5b5780638fda89aa14610b795780638ffa1f2a14610b9957806390df2ecb14610bb9578063918f867414610bce57600080fd5b80633d8b38f6116103c957806362c9cd581161033b578063715018a6116102f4578063715018a614610aa95780637533d78814610abe57806382b12dd714610ade578063833508a714610af45780638985271514610b095780638cfd8f5c14610b2357600080fd5b806362c9cd58146109f65780636352211e14610a1657806366ad5c8a14610a365780636798a98e14610a565780636a62784214610a7657806370a0823114610a8957600080fd5b80634ac3f4ff1161038d5780634ac3f4ff1461091d5780634f6ccce71461094a578063519056361461096a578063531fadbc1461097d5780635b8c41e6146109925780636190a958146109e157600080fd5b80633d8b38f61461087a5780633f1f4fa41461089a57806342842e0e146108c757806342d65a8d146108e7578063482881901461090757600080fd5b80631249c58b1161046d5780631f985078116104265780631f9850781461072157806322a3ecf91461074e57806323b872dd146107d15780632a205e3d146107f15780632f745c591461082657806336ecd1771461084657600080fd5b80631249c58b1461069c57806313966db5146106a457806318160ddd146106ba5780631e04cbf3146106cf5780631e83617e146106e55780631ed9a2d0146106fa57600080fd5b8063081812fc116104bf578063081812fc146105a9578063095ea7b3146105e15780630a7638d1146106015780630b4cad4c1461063c5780630df374831461065c57806310ddb1371461067c57600080fd5b80621d3567146104fb57806301ffc9a71461051d5780630297fdb11461055257806306fdde031461056757806307e0db1714610589575b600080fd5b34801561050757600080fd5b5061051b610516366004614a36565b6110cb565b005b34801561052957600080fd5b5061053d610538366004614adf565b6112fc565b60405190151581526020015b60405180910390f35b34801561055e57600080fd5b5061051b61131f565b34801561057357600080fd5b5061057c611436565b6040516105499190614b4c565b34801561059557600080fd5b5061051b6105a4366004614b5f565b6114c8565b3480156105b557600080fd5b506105c96105c4366004614b7a565b611551565b6040516001600160a01b039091168152602001610549565b3480156105ed57600080fd5b5061051b6105fc366004614bb3565b611578565b34801561060d57600080fd5b5061062e61061c366004614bdf565b601d6020526000908152604090205481565b604051908152602001610549565b34801561064857600080fd5b5061051b610657366004614b7a565b61168d565b34801561066857600080fd5b5061051b610677366004614bfc565b61172d565b34801561068857600080fd5b5061051b610697366004614b5f565b61174c565b61051b6117a4565b3480156106b057600080fd5b5061062e60165481565b3480156106c657600080fd5b5060135461062e565b3480156106db57600080fd5b5061062e61138881565b3480156106f157600080fd5b5061051b611873565b34801561070657600080fd5b5061070f600681565b60405160ff9091168152602001610549565b34801561072d57600080fd5b5061062e61073c366004614bdf565b601e6020526000908152604090205481565b34801561075a57600080fd5b506107a2610769366004614b7a565b600a6020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b0390931660208501529183015215156060820152608001610549565b3480156107dd57600080fd5b5061051b6107ec366004614c18565b6119a2565b3480156107fd57600080fd5b5061081161080c366004614d2c565b6119d4565b60408051928352602083019190915201610549565b34801561083257600080fd5b5061062e610841366004614bb3565b611a58565b34801561085257600080fd5b5061062e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561088657600080fd5b5061053d610895366004614dba565b611aee565b3480156108a657600080fd5b5061062e6108b5366004614b5f565b60036020526000908152604090205481565b3480156108d357600080fd5b5061051b6108e2366004614c18565b611bba565b3480156108f357600080fd5b5061051b610902366004614dba565b611bd5565b34801561091357600080fd5b5061062e60075481565b34801561092957600080fd5b5061062e610938366004614b5f565b60086020526000908152604090205481565b34801561095657600080fd5b5061062e610965366004614b7a565b611c5b565b61051b610978366004614e0c565b611cee565b34801561098957600080fd5b5061070f600281565b34801561099e57600080fd5b5061062e6109ad366004614ec5565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b3480156109ed57600080fd5b5061070f600481565b348015610a0257600080fd5b5061051b610a11366004614b7a565b611d05565b348015610a2257600080fd5b506105c9610a31366004614b7a565b611d56565b348015610a4257600080fd5b5061051b610a51366004614a36565b611db6565b348015610a6257600080fd5b5061051b610a71366004614f22565b611e92565b61051b610a84366004614bdf565b611f5d565b348015610a9557600080fd5b5061062e610aa4366004614bdf565b612113565b348015610ab557600080fd5b5061051b612199565b348015610aca57600080fd5b5061057c610ad9366004614b5f565b6121ab565b348015610aea57600080fd5b5061062e60175481565b348015610b0057600080fd5b5061070f600981565b348015610b1557600080fd5b5060225461053d9060ff1681565b348015610b2f57600080fd5b5061062e610b3e366004614f9c565b600260209081526000928352604080842090915290825290205481565b348015610b6757600080fd5b506000546001600160a01b03166105c9565b348015610b8557600080fd5b5061051b610b94366004614fcf565b612245565b348015610ba557600080fd5b5061051b610bb4366004614fea565b6122a2565b348015610bc557600080fd5b5061070f600881565b348015610bda57600080fd5b5061062e61271081565b348015610bf057600080fd5b506004546105c9906001600160a01b031681565b348015610c1057600080fd5b5061057c6124ea565b348015610c2557600080fd5b5061051b610c34366004614b7a565b6124f9565b348015610c4557600080fd5b5061070f600381565b348015610c5a57600080fd5b5061051b610c69366004614bfc565b61253a565b348015610c7a57600080fd5b5061057c610c89366004614b5f565b6125f1565b348015610c9a57600080fd5b5061051b610ca936600461501e565b612707565b348015610cba57600080fd5b5061051b610cc9366004614bdf565b612716565b348015610cda57600080fd5b5061051b610ce9366004614dba565b612786565b61051b610cfc3660046150d3565b61280f565b348015610d0d57600080fd5b50610d16600181565b60405161ffff9091168152602001610549565b348015610d3557600080fd5b506105c97f000000000000000000000000000000000000000000000000000000000000000081565b348015610d6957600080fd5b5061051b610d78366004615188565b61281e565b348015610d8957600080fd5b5061051b610d98366004614bdf565b612856565b348015610da957600080fd5b5061062e610db8366004614bdf565b601c6020526000908152604090205481565b348015610dd657600080fd5b506018546105c9906001600160a01b031681565b348015610df657600080fd5b5061070f600181565b348015610e0b57600080fd5b5061070f600781565b348015610e2057600080fd5b5061057c610e2f366004614b7a565b6128ac565b348015610e4057600080fd5b5061051b610e4f3660046151f3565b6128f6565b348015610e6057600080fd5b5061051b610e6f36600461525e565b612a2d565b348015610e8057600080fd5b5061062e610e8f366004614bdf565b601f6020526000908152604090205481565b348015610ead57600080fd5b5061062e60155481565b348015610ec357600080fd5b5061051b610ed2366004614bfc565b612ac2565b61051b610ee5366004614a36565b612b72565b348015610ef657600080fd5b5061051b610f053660046152cc565b612d88565b348015610f1657600080fd5b5061051b610f25366004614bb3565b612e3a565b348015610f3657600080fd5b5061062e601b5481565b348015610f4c57600080fd5b5061062e7f000000000000000000000000000000000000000000000000000000000000000081565b348015610f8057600080fd5b5061053d610f8f366004615308565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b348015610fc957600080fd5b5061070f600581565b348015610fde57600080fd5b5061062e60195481565b348015610ff457600080fd5b5061062e601a5481565b34801561100a57600080fd5b5061051b611019366004614dba565b612e9f565b34801561102a57600080fd5b5061051b611039366004614b7a565b612ef9565b34801561104a57600080fd5b50610811611059366004615341565b612f3a565b34801561106a57600080fd5b5061051b611079366004614bdf565b612f68565b34801561108a57600080fd5b5061057c6110993660046153ba565b612fde565b3480156110aa57600080fd5b5061062e6110b9366004614b5f565b60096020526000908152604090205481565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146111485760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff86166000908152600160205260408120805461116690615407565b80601f016020809104026020016040519081016040528092919081815260200182805461119290615407565b80156111df5780601f106111b4576101008083540402835291602001916111df565b820191906000526020600020905b8154815290600101906020018083116111c257829003601f168201915b505050505090508051868690501480156111fa575060008151115b80156112225750805160208201206040516112189088908890615441565b6040518091039020145b61127d5760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b606482015260840161113f565b6112f38787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061309192505050565b50505050505050565b60006001600160e01b03198216158061131957506113198261310a565b92915050565b336000908152601e602052604090205461133c811515600661312f565b336000908152601e60209081526040808320839055601f90915281208054839290611368908490615467565b9091555050604051600090339083908381818185875af1925050503d80600081146113af576040519150601f19603f3d011682016040523d82523d6000602084013e6113b4565b606091505b50509050806113fc5760405162461bcd60e51b81526020600482015260146024820152732330b4b632b2103a379039b2b7321022ba3432b960611b604482015260640161113f565b60405182815233907fa6183a81b1ce4e0d90156f6ec9b6f2d13c204d11884302b40b47bb456fb59156906020015b60405180910390a25050565b6060600b805461144590615407565b80601f016020809104026020016040519081016040528092919081815260200182805461147190615407565b80156114be5780601f10611493576101008083540402835291602001916114be565b820191906000526020600020905b8154815290600101906020018083116114a157829003601f168201915b5050505050905090565b6114d0613152565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b15801561153657600080fd5b505af115801561154a573d6000803e3d6000fd5b5050505050565b600061155c826131ac565b506000908152600f60205260409020546001600160a01b031690565b600061158382611d56565b9050806001600160a01b0316836001600160a01b0316036115f05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161113f565b336001600160a01b038216148061160c575061160c8133610f8f565b61167e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000606482015260840161113f565b61168883836131fc565b505050565b611695613152565b600081116116f15760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b606482015260840161113f565b60078190556040518181527ffebbc4f8bb9ec2313950c718d43123124b15778efda4c1f1d529de2995b4f34d906020015b60405180910390a150565b611735613152565b61ffff909116600090815260036020526040902055565b611754613152565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb1379060240161151c565b6117ac61326a565b6015546016546117df7f00000000000000000000000000000000000000000000000000000000000000008310600261312f565b6117ed81341015600361312f565b6015600081546117fc9061547a565b9190508190555080601960008282546118159190615467565b90915550611825905033836132c3565b6040805182815260006020820181905291849133917faf10eb5876c114d027970b3131ea6479da41c88b7d3ba0d093aea9a4126444eb910160405180910390a450506118716001600655565b565b61187b6132dd565b61188361326a565b601954611893811515600661312f565b60006019819055601a805483928392916118ae908490615467565b90915550506018546040516001600160a01b0390911690600090829084908381818185875af1925050503d8060008114611904576040519150601f19603f3d011682016040523d82523d6000602084013e611909565b606091505b50509050806119515760405162461bcd60e51b81526020600482015260146024820152732330b4b632b2103a379039b2b7321022ba3432b960611b604482015260640161113f565b816001600160a01b03167f582c87414358df39212a275853c71633d2dc65d15ae92cc5718e7438766bea768460405161198c91815260200190565b60405180910390a2505050506118716001600655565b6119ad335b826132f6565b6119c95760405162461bcd60e51b815260040161113f90615493565b611688838383613374565b6000803063f235364188886119e8896134e5565b88886040518663ffffffff1660e01b8152600401611a0a95949392919061551b565b6040805180830381865afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190615572565b915091509550959350505050565b6000611a6383612113565b8210611ac55760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161113f565b506001600160a01b03919091166000908152601160209081526040808320938352929052205490565b61ffff831660009081526001602052604081208054829190611b0f90615407565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3b90615407565b8015611b885780601f10611b5d57610100808354040283529160200191611b88565b820191906000526020600020905b815481529060010190602001808311611b6b57829003601f168201915b505050505090508383604051611b9f929190615441565b60405180910390208180519060200120149150509392505050565b6116888383836040518060200160405280600081525061281e565b611bdd613152565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d90611c2d908690869086906004016155bf565b600060405180830381600087803b158015611c4757600080fd5b505af11580156112f3573d6000803e3d6000fd5b6000611c6660135490565b8210611cc95760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161113f565b60138281548110611cdc57611cdc6155dd565b90600052602060002001549050919050565b6112f3878787611cfd886134e5565b878787613530565b611d0d613152565b611d1d611388821115600861312f565b601b805490829055604051829082907f5520877bcd003e98f39712fa0194b5172c7c1a2f2ec8a1a9deb2b5a79c2525e890600090a35050565b6000818152600d60205260408120546001600160a01b0316806113195760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161113f565b333014611e145760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b606482015260840161113f565b611e8a8686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506135bc92505050565b505050505050565b611e9a613152565b611eaa612710821115600861312f565b60005b82811015611f0d5781601c6000868685818110611ecc57611ecc6155dd565b9050602002016020810190611ee19190614bdf565b6001600160a01b0316815260208101919091526040016000205580611f058161547a565b915050611ead565b508282604051611f1e9291906155f3565b604051908190038120828252907f534f5101174d9c5177797e870102d53e013a9d6b33436ea06de20371c65078e89060200160405180910390a2505050565b611f6561326a565b601554601654611f987f00000000000000000000000000000000000000000000000000000000000000008310600261312f565b611fa681341015600361312f565b611fd16001600160a01b0384163314801590611fca57506001600160a01b03841615155b600961312f565b601560008154611fe09061547a565b909155506001600160a01b0383166000908152601c602052604081205490811561200a578161200e565b601b545b9050600061271061201f8386615635565b612029919061564c565b90506000612037828661566e565b6001600160a01b0388166000908152601e6020526040812080549293508492909190612064908490615467565b90915550506001600160a01b0387166000908152601d60205260408120805490919061208f9061547a565b9190508190555080601960008282546120a89190615467565b909155506120b8905033876132c3565b60408051828152602081018490526001600160a01b03891691889133917faf10eb5876c114d027970b3131ea6479da41c88b7d3ba0d093aea9a4126444eb910160405180910390a45050505050506121106001600655565b50565b60006001600160a01b03821661217d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b606482015260840161113f565b506001600160a01b03166000908152600e602052604090205490565b6121a1613152565b6118716000613725565b600160205260009081526040902080546121c490615407565b80601f01602080910402602001604051908101604052809291908181526020018280546121f090615407565b801561223d5780601f106122125761010080835404028352916020019161223d565b820191906000526020600020905b81548152906001019060200180831161222057829003601f168201915b505050505081565b61224d613152565b6022546122659060ff1615158215151415600161312f565b6022805460ff19168215159081179091556040517f86f6d3aac457fe4bb989f97e01063ec20dc5442373c5c9a0617a07c7b5362f6b90600090a250565b6122aa61326a565b80516020808301919091206000818152600a90925260409091206002015460ff1661230b5760405162461bcd60e51b81526020600482015260116024820152701b9bc818dc99591a5d1cc81cdd1bdc9959607a1b604482015260640161113f565b60008280602001905181019061232191906156c6565b6000848152600a60205260408120805460019091015492945090925061235d9161ffff8216916201000090046001600160a01b03169085613775565b6000848152600a602052604090206001015490915081116123d25760405162461bcd60e51b815260206004820152602960248201527f6e6f7420656e6f7567682067617320746f2070726f6365737320637265646974604482015268103a3930b739b332b960b91b606482015260840161113f565b81518103612449576000838152600a602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba2339061243c9085815260200190565b60405180910390a16124dd565b604080516080810182526000858152600a6020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b5050506121106001600655565b6060600c805461144590615407565b612501613152565b6017805490829055604051829082907ff87f51c5c0d01564ccf3da315f76df881b0309297d68dde4303ab79a0f1b84cf90600090a35050565b612542613152565b6000811161259d5760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b606482015260840161113f565b61ffff8216600081815260086020908152604091829020849055815192835282018390527f7315f7654d594ead24a30160ed9ba2d23247f543016b918343591e93d7afdb6d91015b60405180910390a15050565b61ffff811660009081526001602052604081208054606092919061261490615407565b80601f016020809104026020016040519081016040528092919081815260200182805461264090615407565b801561268d5780601f106126625761010080835404028352916020019161268d565b820191906000526020600020905b81548152906001019060200180831161267057829003601f168201915b5050505050905080516000036126e55760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f7264000000604482015260640161113f565b6127006000601483516126f8919061566e565b8391906137c1565b9392505050565b6127123383836138ce565b5050565b61271e613152565b6127346001600160a01b0382161515600561312f565b601880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f649c5e3d0ed183894196148e193af316452b0037e77d2ff0fef23b7dc722bed090600090a35050565b61278e613152565b8181306040516020016127a393929190615780565b60408051601f1981840301815291815261ffff85166000908152600160205220906127ce90826157ec565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051612802939291906155bf565b60405180910390a1505050565b6112f387878787878787613530565b61282833836132f6565b6128445760405162461bcd60e51b815260040161113f90615493565b6128508484848461399c565b50505050565b61285e613152565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b90602001611722565b60606128c16128ba836139cf565b600461312f565b60216128cc836139ec565b60206040516020016128e09392919061591e565b6040516020818303038152906040529050919050565b6128fe613152565b6022546129109060ff1615600161312f565b60006021805461291f90615407565b80601f016020809104026020016040519081016040528092919081815260200182805461294b90615407565b80156129985780601f1061296d57610100808354040283529160200191612998565b820191906000526020600020905b81548152906001019060200180831161297b57829003601f168201915b505050505090508484602191826129b0929190615951565b5060206129be838583615951565b5084846040516129cf929190615441565b6040518091039020816040516129e59190615a10565b60405180910390207fc354b4e8393ca297df0d60baaffdd112d7eaa0382a111cc8693009e8f404d9398585604051612a1e929190615a2c565b60405180910390a35050505050565b612a35613152565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c90612a899088908890889088908890600401615a40565b600060405180830381600087803b158015612aa357600080fd5b505af1158015612ab7573d6000803e3d6000fd5b505050505050505050565b612aca613152565b60008111612b265760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b606482015260840161113f565b61ffff8216600081815260096020908152604091829020849055815192835282018390527fc46df2983228ac2d9754e94a0d565e6671665dc8ad38602bc8e544f0685a29fb91016125e5565b61ffff86166000908152600560205260408082209051612b959088908890615441565b90815260408051602092819003830190206001600160401b03871660009081529252902054905080612c155760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b606482015260840161113f565b808383604051612c26929190615441565b604051809103902014612c855760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b606482015260840161113f565b61ffff87166000908152600560205260408082209051612ca89089908990615441565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252612d40918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506135bc92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e58787878785604051612d77959493929190615a6e565b60405180910390a150505050505050565b612d90613152565b60008111612dd85760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b604482015260640161113f565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001612802565b612e42613152565b612e52612710821115600861312f565b6001600160a01b0382166000818152601c602052604090819020839055517f081217f104a9c8ce8b5570732f898968cb602b62d54965af794344e689a625909061142a9084815260200190565b612ea7613152565b61ffff83166000908152600160205260409020612ec5828483615951565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab838383604051612802939291906155bf565b612f01613152565b6016805490829055604051829082907fd8f648a37e4afe1c401d97caaa06358d2e2725ac008214ce9f5497991e65439690600090a35050565b600080612f4a8787878787613a7e565b6017549193509150612f5c9083615467565b91509550959350505050565b612f70613152565b6001600160a01b038116612fd55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161113f565b61211081613725565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc90608401600060405180830381865afa15801561305e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130869190810190615aa9565b90505b949350505050565b6000806130f45a60966366ad5c8a60e01b898989896040516024016130b99493929190615add565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190613b49565b9150915081611e8a57611e8a8686868685613bd3565b60006001600160e01b0319821663780e9d6360e01b1480611319575061131982613c70565b81612712576040516302a9557160e61b815260ff8216600482015260240161113f565b6000546001600160a01b031633146118715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161113f565b6131b5816139cf565b6121105760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161113f565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061323182611d56565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6002600654036132bc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161113f565b6002600655565b612712828260405180602001604052806000815250613c8d565b601854611871906001600160a01b03163314600761312f565b60008061330283611d56565b9050806001600160a01b0316846001600160a01b0316148061334957506001600160a01b0380821660009081526010602090815260408083209388168352929052205460ff165b806130895750836001600160a01b031661336284611551565b6001600160a01b031614949350505050565b826001600160a01b031661338782611d56565b6001600160a01b0316146133ad5760405162461bcd60e51b815260040161113f90615b1b565b6001600160a01b03821661340f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161113f565b61341c8383836001613cc0565b826001600160a01b031661342f82611d56565b6001600160a01b0316146134555760405162461bcd60e51b815260040161113f90615b1b565b6000818152600f6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600e8552838620805460001901905590871680865283862080546001019055868652600d90945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061351f5761351f6155dd565b602090810291909101015292915050565b601754600061353f823461566e565b905081601960008282546135539190615467565b9091555061356990508989898989898988613ccc565b8761ffff16896001600160a01b03167f81124ef096134d3d08199ac5bc8e55569b17dcbe54f085c78b63a8da7f789bac846040516135a991815260200190565b60405180910390a3505050505050505050565b600080828060200190518101906135d391906156c6565b6014820151919350915060006135eb88838386613775565b905082518110156136bf5784516020808701919091206040805160808101825261ffff808d1682526001600160a01b038088168387019081528385018881526001606086018181526000898152600a909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad7906136b59083908990615b60565b60405180910390a1505b816001600160a01b0316876040516136d79190615a10565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d990265866040516137139190615b79565b60405180910390a45050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000825b8251811015613086576007545a10613086576137af86868584815181106137a2576137a26155dd565b6020026020010151613ea1565b806137b98161547a565b915050613779565b6060816137cf81601f615467565b101561380e5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015260640161113f565b6138188284615467565b8451101561385c5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b604482015260640161113f565b60608215801561387b57604051915060008252602082016040526138c5565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156138b457805183526020928301920161389c565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b03160361392f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161113f565b6001600160a01b03838116600081815260106020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6139a7848484613374565b6139b384848484613f01565b6128505760405162461bcd60e51b815260040161113f90615b8c565b6000908152600d60205260409020546001600160a01b0316151590565b606060006139f983613fff565b60010190506000816001600160401b03811115613a1857613a18614c59565b6040519080825280601f01601f191660200182016040528015613a42576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084613a4c57509392505050565b60008060008686604051602001613a96929190615bde565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb1090613afa908b90309086908b908b90600401615c0c565b6040805180830381865afa158015613b16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b3a9190615572565b92509250509550959350505050565b6000606060008060008661ffff166001600160401b03811115613b6e57613b6e614c59565b6040519080825280601f01601f191660200182016040528015613b98576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613bba578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff16815260200190815260200160002085604051613c049190615a10565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c90613c619087908790879087908790615c54565b60405180910390a15050505050565b60006001600160e01b0319821615806113195750611319826140d7565b613c978383614117565b613ca46000848484613f01565b6116885760405162461bcd60e51b815260040161113f90615b8c565b61285084848484614292565b6000855111613d135760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b604482015260640161113f565b845160011480613d37575061ffff8716600090815260086020526040902054855111155b613d8e5760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b606482015260840161113f565b60005b8551811015613dd157613dbf898989898581518110613db257613db26155dd565b60200260200101516143bf565b80613dc98161547a565b915050613d91565b5060008686604051602001613de7929190615bde565b6040516020818303038152906040529050613e2c886001858951600960008e61ffff1661ffff16815260200190815260200160002054613e279190615635565b6144aa565b613e3a888287878787614589565b86604051613e489190615a10565b6040518091039020896001600160a01b03168961ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a89604051613e8e9190615b79565b60405180910390a4505050505050505050565b613eaa816139cf565b1580613ed65750613eba816139cf565b8015613ed6575030613ecb82611d56565b6001600160a01b0316145b613edf57600080fd5b613ee8816139cf565b613ef65761168882826132c3565b611688308383613374565b60006001600160a01b0384163b15613ff757604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613f45903390899088908890600401615ca6565b6020604051808303816000875af1925050508015613f80575060408051601f3d908101601f19168201909252613f7d91810190615ce3565b60015b613fdd573d808015613fae576040519150601f19603f3d011682016040523d82523d6000602084013e613fb3565b606091505b508051600003613fd55760405162461bcd60e51b815260040161113f90615b8c565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613089565b506001613089565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061403e5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061406a576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061408857662386f26fc10000830492506010015b6305f5e10083106140a0576305f5e100830492506008015b61271083106140b457612710830492506004015b606483106140c6576064830492506002015b600a83106113195760010192915050565b60006001600160e01b031982166380ac58cd60e01b148061410857506001600160e01b03198216635b5e139f60e01b145b8061131957506113198261472e565b6001600160a01b03821661416d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161113f565b614176816139cf565b156141c35760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161113f565b6141d1600083836001613cc0565b6141da816139cf565b156142275760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161113f565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60018111156143015760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b606482015260840161113f565b816001600160a01b03851661435d5761435881601380546000838152601460205260408120829055600182018355919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900155565b614380565b836001600160a01b0316856001600160a01b031614614380576143808582614763565b6001600160a01b03841661439c5761439781614800565b61154a565b846001600160a01b0316846001600160a01b03161461154a5761154a84826148af565b6143c8336119a7565b61442b5760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b606482015260840161113f565b836001600160a01b031661443e82611d56565b6001600160a01b03161461449f5760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b606482015260840161113f565b612850843083613374565b60006144b5836148f3565b61ffff8087166000908152600260209081526040808320938916835292905290812054919250906144e7908490615467565b9050600081116145395760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f7420736574000000000000604482015260640161113f565b80821015611e8a5760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f770000000000604482015260640161113f565b61ffff8616600090815260016020526040812080546145a790615407565b80601f01602080910402602001604051908101604052809291908181526020018280546145d390615407565b80156146205780601f106145f557610100808354040283529160200191614620565b820191906000526020600020905b81548152906001019060200180831161460357829003601f168201915b5050505050905080516000036146915760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b606482015260840161113f565b61469c87875161494f565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c58031009084906146f3908b9086908c908c908c908c90600401615d00565b6000604051808303818588803b15801561470c57600080fd5b505af1158015614720573d6000803e3d6000fd5b505050505050505050505050565b60006001600160e01b031982166322bac5d960e01b148061131957506301ffc9a760e01b6001600160e01b0319831614611319565b6000600161477084612113565b61477a919061566e565b6000838152601260205260409020549091508082146147cd576001600160a01b03841660009081526011602090815260408083208584528252808320548484528184208190558352601290915290208190555b5060009182526012602090815260408084208490556001600160a01b039094168352601181528383209183525290812055565b6013546000906148129060019061566e565b6000838152601460205260408120546013805493945090928490811061483a5761483a6155dd565b90600052602060002001549050806013838154811061485b5761485b6155dd565b600091825260208083209091019290925582815260149091526040808220849055858252812055601380548061489357614893615d67565b6001900381819060005260206000200160009055905550505050565b60006148ba83612113565b6001600160a01b039093166000908152601160209081526040808320868452825280832085905593825260129052919091209190915550565b60006022825110156149475760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d7300000000604482015260640161113f565b506022015190565b61ffff82166000908152600360205260408120549081900361497057506127105b808211156116885760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c61726765604482015260640161113f565b803561ffff811681146149d257600080fd5b919050565b60008083601f8401126149e957600080fd5b5081356001600160401b03811115614a0057600080fd5b602083019150836020828501011115614a1857600080fd5b9250929050565b80356001600160401b03811681146149d257600080fd5b60008060008060008060808789031215614a4f57600080fd5b614a58876149c0565b955060208701356001600160401b0380821115614a7457600080fd5b614a808a838b016149d7565b9097509550859150614a9460408a01614a1f565b94506060890135915080821115614aaa57600080fd5b50614ab789828a016149d7565b979a9699509497509295939492505050565b6001600160e01b03198116811461211057600080fd5b600060208284031215614af157600080fd5b813561270081614ac9565b60005b83811015614b17578181015183820152602001614aff565b50506000910152565b60008151808452614b38816020860160208601614afc565b601f01601f19169290920160200192915050565b6020815260006127006020830184614b20565b600060208284031215614b7157600080fd5b612700826149c0565b600060208284031215614b8c57600080fd5b5035919050565b6001600160a01b038116811461211057600080fd5b80356149d281614b93565b60008060408385031215614bc657600080fd5b8235614bd181614b93565b946020939093013593505050565b600060208284031215614bf157600080fd5b813561270081614b93565b60008060408385031215614c0f57600080fd5b614bd1836149c0565b600080600060608486031215614c2d57600080fd5b8335614c3881614b93565b92506020840135614c4881614b93565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614c9757614c97614c59565b604052919050565b60006001600160401b03821115614cb857614cb8614c59565b50601f01601f191660200190565b600082601f830112614cd757600080fd5b8135614cea614ce582614c9f565b614c6f565b818152846020838601011115614cff57600080fd5b816020850160208301376000918101602001919091529392505050565b803580151581146149d257600080fd5b600080600080600060a08688031215614d4457600080fd5b614d4d866149c0565b945060208601356001600160401b0380821115614d6957600080fd5b614d7589838a01614cc6565b955060408801359450614d8a60608901614d1c565b93506080880135915080821115614da057600080fd5b50614dad88828901614cc6565b9150509295509295909350565b600080600060408486031215614dcf57600080fd5b614dd8846149c0565b925060208401356001600160401b03811115614df357600080fd5b614dff868287016149d7565b9497909650939450505050565b600080600080600080600060e0888a031215614e2757600080fd5b8735614e3281614b93565b9650614e40602089016149c0565b955060408801356001600160401b0380821115614e5c57600080fd5b614e688b838c01614cc6565b965060608a0135955060808a01359150614e8182614b93565b90935060a089013590614e9382614b93565b90925060c08901359080821115614ea957600080fd5b50614eb68a828b01614cc6565b91505092959891949750929550565b600080600060608486031215614eda57600080fd5b614ee3846149c0565b925060208401356001600160401b03811115614efe57600080fd5b614f0a86828701614cc6565b925050614f1960408501614a1f565b90509250925092565b600080600060408486031215614f3757600080fd5b83356001600160401b0380821115614f4e57600080fd5b818601915086601f830112614f6257600080fd5b813581811115614f7157600080fd5b8760208260051b8501011115614f8657600080fd5b6020928301989097509590910135949350505050565b60008060408385031215614faf57600080fd5b614fb8836149c0565b9150614fc6602084016149c0565b90509250929050565b600060208284031215614fe157600080fd5b61270082614d1c565b600060208284031215614ffc57600080fd5b81356001600160401b0381111561501257600080fd5b61308984828501614cc6565b6000806040838503121561503157600080fd5b823561503c81614b93565b9150614fc660208401614d1c565b60006001600160401b0382111561506357615063614c59565b5060051b60200190565b600082601f83011261507e57600080fd5b8135602061508e614ce58361504a565b82815260059290921b840181019181810190868411156150ad57600080fd5b8286015b848110156150c857803583529183019183016150b1565b509695505050505050565b600080600080600080600060e0888a0312156150ee57600080fd5b87356150f981614b93565b9650615107602089016149c0565b955060408801356001600160401b038082111561512357600080fd5b61512f8b838c01614cc6565b965060608a013591508082111561514557600080fd5b6151518b838c0161506d565b955060808a0135915061516382614b93565b81945061517260a08b01614ba8565b935060c08a0135915080821115614ea957600080fd5b6000806000806080858703121561519e57600080fd5b84356151a981614b93565b935060208501356151b981614b93565b92506040850135915060608501356001600160401b038111156151db57600080fd5b6151e787828801614cc6565b91505092959194509250565b6000806000806040858703121561520957600080fd5b84356001600160401b038082111561522057600080fd5b61522c888389016149d7565b9096509450602087013591508082111561524557600080fd5b50615252878288016149d7565b95989497509550505050565b60008060008060006080868803121561527657600080fd5b61527f866149c0565b945061528d602087016149c0565b93506040860135925060608601356001600160401b038111156152af57600080fd5b6152bb888289016149d7565b969995985093965092949392505050565b6000806000606084860312156152e157600080fd5b6152ea846149c0565b92506152f8602085016149c0565b9150604084013590509250925092565b6000806040838503121561531b57600080fd5b823561532681614b93565b9150602083013561533681614b93565b809150509250929050565b600080600080600060a0868803121561535957600080fd5b615362866149c0565b945060208601356001600160401b038082111561537e57600080fd5b61538a89838a01614cc6565b955060408801359150808211156153a057600080fd5b6153ac89838a0161506d565b9450614d8a60608901614d1c565b600080600080608085870312156153d057600080fd5b6153d9856149c0565b93506153e7602086016149c0565b925060408501356153f781614b93565b9396929550929360600135925050565b600181811c9082168061541b57607f821691505b60208210810361543b57634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561131957611319615451565b60006001820161548c5761548c615451565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b600081518084526020808501945080840160005b83811015615510578151875295820195908201906001016154f4565b509495945050505050565b61ffff8616815260a06020820152600061553860a0830187614b20565b828103604084015261554a81876154e0565b9050841515606084015282810360808401526155668185614b20565b98975050505050505050565b6000806040838503121561558557600080fd5b505080516020909101519092909150565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff84168152604060208201526000613086604083018486615596565b634e487b7160e01b600052603260045260246000fd5b60008184825b8581101561562a57813561560c81614b93565b6001600160a01b0316835260209283019291909101906001016155f9565b509095945050505050565b808202811582820484141761131957611319615451565b60008261566957634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561131957611319615451565b600082601f83011261569257600080fd5b81516156a0614ce582614c9f565b8181528460208386010111156156b557600080fd5b613089826020830160208701614afc565b600080604083850312156156d957600080fd5b82516001600160401b03808211156156f057600080fd5b6156fc86838701615681565b935060209150818501518181111561571357600080fd5b85019050601f8101861361572657600080fd5b8051615734614ce58261504a565b81815260059190911b8201830190838101908883111561575357600080fd5b928401925b8284101561577157835182529284019290840190615758565b80955050505050509250929050565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b601f82111561168857600081815260208120601f850160051c810160208610156157cd5750805b601f850160051c820191505b81811015611e8a578281556001016157d9565b81516001600160401b0381111561580557615805614c59565b615819816158138454615407565b846157a6565b602080601f83116001811461584e57600084156158365750858301515b600019600386901b1c1916600185901b178555611e8a565b600085815260208120601f198616915b8281101561587d5788860151825594840194600190910190840161585e565b508582101561589b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081546158b881615407565b600182811680156158d057600181146158e557615914565b60ff1984168752821515830287019450615914565b8560005260208060002060005b8581101561590b5781548a8201529084019082016158f2565b50505082870194505b5050505092915050565b600061592a82866158ab565b845161593a818360208901614afc565b615946818301866158ab565b979650505050505050565b6001600160401b0383111561596857615968614c59565b61597c836159768354615407565b836157a6565b6000601f8411600181146159b057600085156159985750838201355b600019600387901b1c1916600186901b17835561154a565b600083815260209020601f19861690835b828110156159e157868501358255602094850194600190920191016159c1565b50868210156159fe5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008251615a22818460208701614afc565b9190910192915050565b602081526000613089602083018486615596565b600061ffff808816835280871660208401525084604083015260806060830152615946608083018486615596565b61ffff86168152608060208201526000615a8c608083018688615596565b6001600160401b0394909416604083015250606001529392505050565b600060208284031215615abb57600080fd5b81516001600160401b03811115615ad157600080fd5b61308984828501615681565b61ffff85168152608060208201526000615afa6080830186614b20565b6001600160401b038516604084015282810360608401526159468185614b20565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b8281526040602082015260006130896040830184614b20565b60208152600061270060208301846154e0565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b604081526000615bf16040830185614b20565b8281036020840152615c0381856154e0565b95945050505050565b61ffff861681526001600160a01b038516602082015260a060408201819052600090615c3a90830186614b20565b841515606084015282810360808401526155668185614b20565b61ffff8616815260a060208201526000615c7160a0830187614b20565b6001600160401b03861660408401528281036060840152615c928186614b20565b905082810360808401526155668185614b20565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615cd990830184614b20565b9695505050505050565b600060208284031215615cf557600080fd5b815161270081614ac9565b61ffff8716815260c060208201526000615d1d60c0830188614b20565b8281036040840152615d2f8188614b20565b6001600160a01b0387811660608601528616608085015283810360a08501529050615d5a8185614b20565b9998505050505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220227fbff534a29408eec9ca125e281be5ca2bd975d586367940279a72a9410a4564736f6c6343000813003300000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd70000000000000000000000000000000000000000000000000000000002160ec10000000000000000000000000000000000000000000000000000000002625a0000000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000009184e72a000000000000000000000000000000bb3c144ccdd0c5d5400a9b4a416c32002110000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106104f65760003560e01c80638da5cb5b1161028c578063c74046f91161015a578063e0381d7d116100cc578063eb8d72b711610085578063eb8d72b714610ffe578063eddd0d9c1461101e578063f23536411461103e578063f2fde38b1461105e578063f5ecbdbc1461107e578063fa25f9b61461109e57600080fd5b8063e0381d7d14610f2a578063e1d4c87014610f40578063e985e9c514610f74578063e9c9637914610fbd578063ea0d9e1814610fd2578063eb56c48514610fe857600080fd5b8063d082e3811161011e578063d082e38114610ea1578063d12473a514610eb7578063d1deba1f14610ed7578063dd0081c714610bce578063df2a5b3b14610eea578063df329fc114610f0a57600080fd5b8063c74046f914610dff578063c87b56dd14610e14578063cbc1418a14610e34578063cbed8b9c14610e54578063cf836dc314610e7457600080fd5b8063a22cb465116101fe578063b88d4fde116101b7578063b88d4fde14610d5d578063baf3292d14610d7d578063c2690cb614610d9d578063c415b95c14610dca578063c446183414610bce578063c6f0995614610dea57600080fd5b8063a22cb46514610c8e578063a42dce8014610cae578063a6c3d16514610cce578063ab3ffb9314610cee578063af3fb21c14610d01578063b353aaa714610d2957600080fd5b8063950c8a7411610250578063950c8a7414610be457806395d89b4114610c04578063998cdf8314610c195780639ae0088314610c395780639ea5d6b114610c4e5780639f38369a14610c6e57600080fd5b80638da5cb5b14610b5b5780638fda89aa14610b795780638ffa1f2a14610b9957806390df2ecb14610bb9578063918f867414610bce57600080fd5b80633d8b38f6116103c957806362c9cd581161033b578063715018a6116102f4578063715018a614610aa95780637533d78814610abe57806382b12dd714610ade578063833508a714610af45780638985271514610b095780638cfd8f5c14610b2357600080fd5b806362c9cd58146109f65780636352211e14610a1657806366ad5c8a14610a365780636798a98e14610a565780636a62784214610a7657806370a0823114610a8957600080fd5b80634ac3f4ff1161038d5780634ac3f4ff1461091d5780634f6ccce71461094a578063519056361461096a578063531fadbc1461097d5780635b8c41e6146109925780636190a958146109e157600080fd5b80633d8b38f61461087a5780633f1f4fa41461089a57806342842e0e146108c757806342d65a8d146108e7578063482881901461090757600080fd5b80631249c58b1161046d5780631f985078116104265780631f9850781461072157806322a3ecf91461074e57806323b872dd146107d15780632a205e3d146107f15780632f745c591461082657806336ecd1771461084657600080fd5b80631249c58b1461069c57806313966db5146106a457806318160ddd146106ba5780631e04cbf3146106cf5780631e83617e146106e55780631ed9a2d0146106fa57600080fd5b8063081812fc116104bf578063081812fc146105a9578063095ea7b3146105e15780630a7638d1146106015780630b4cad4c1461063c5780630df374831461065c57806310ddb1371461067c57600080fd5b80621d3567146104fb57806301ffc9a71461051d5780630297fdb11461055257806306fdde031461056757806307e0db1714610589575b600080fd5b34801561050757600080fd5b5061051b610516366004614a36565b6110cb565b005b34801561052957600080fd5b5061053d610538366004614adf565b6112fc565b60405190151581526020015b60405180910390f35b34801561055e57600080fd5b5061051b61131f565b34801561057357600080fd5b5061057c611436565b6040516105499190614b4c565b34801561059557600080fd5b5061051b6105a4366004614b5f565b6114c8565b3480156105b557600080fd5b506105c96105c4366004614b7a565b611551565b6040516001600160a01b039091168152602001610549565b3480156105ed57600080fd5b5061051b6105fc366004614bb3565b611578565b34801561060d57600080fd5b5061062e61061c366004614bdf565b601d6020526000908152604090205481565b604051908152602001610549565b34801561064857600080fd5b5061051b610657366004614b7a565b61168d565b34801561066857600080fd5b5061051b610677366004614bfc565b61172d565b34801561068857600080fd5b5061051b610697366004614b5f565b61174c565b61051b6117a4565b3480156106b057600080fd5b5061062e60165481565b3480156106c657600080fd5b5060135461062e565b3480156106db57600080fd5b5061062e61138881565b3480156106f157600080fd5b5061051b611873565b34801561070657600080fd5b5061070f600681565b60405160ff9091168152602001610549565b34801561072d57600080fd5b5061062e61073c366004614bdf565b601e6020526000908152604090205481565b34801561075a57600080fd5b506107a2610769366004614b7a565b600a6020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b0390931660208501529183015215156060820152608001610549565b3480156107dd57600080fd5b5061051b6107ec366004614c18565b6119a2565b3480156107fd57600080fd5b5061081161080c366004614d2c565b6119d4565b60408051928352602083019190915201610549565b34801561083257600080fd5b5061062e610841366004614bb3565b611a58565b34801561085257600080fd5b5061062e7f0000000000000000000000000000000000000000000000000000000002160ec181565b34801561088657600080fd5b5061053d610895366004614dba565b611aee565b3480156108a657600080fd5b5061062e6108b5366004614b5f565b60036020526000908152604090205481565b3480156108d357600080fd5b5061051b6108e2366004614c18565b611bba565b3480156108f357600080fd5b5061051b610902366004614dba565b611bd5565b34801561091357600080fd5b5061062e60075481565b34801561092957600080fd5b5061062e610938366004614b5f565b60086020526000908152604090205481565b34801561095657600080fd5b5061062e610965366004614b7a565b611c5b565b61051b610978366004614e0c565b611cee565b34801561098957600080fd5b5061070f600281565b34801561099e57600080fd5b5061062e6109ad366004614ec5565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b3480156109ed57600080fd5b5061070f600481565b348015610a0257600080fd5b5061051b610a11366004614b7a565b611d05565b348015610a2257600080fd5b506105c9610a31366004614b7a565b611d56565b348015610a4257600080fd5b5061051b610a51366004614a36565b611db6565b348015610a6257600080fd5b5061051b610a71366004614f22565b611e92565b61051b610a84366004614bdf565b611f5d565b348015610a9557600080fd5b5061062e610aa4366004614bdf565b612113565b348015610ab557600080fd5b5061051b612199565b348015610aca57600080fd5b5061057c610ad9366004614b5f565b6121ab565b348015610aea57600080fd5b5061062e60175481565b348015610b0057600080fd5b5061070f600981565b348015610b1557600080fd5b5060225461053d9060ff1681565b348015610b2f57600080fd5b5061062e610b3e366004614f9c565b600260209081526000928352604080842090915290825290205481565b348015610b6757600080fd5b506000546001600160a01b03166105c9565b348015610b8557600080fd5b5061051b610b94366004614fcf565b612245565b348015610ba557600080fd5b5061051b610bb4366004614fea565b6122a2565b348015610bc557600080fd5b5061070f600881565b348015610bda57600080fd5b5061062e61271081565b348015610bf057600080fd5b506004546105c9906001600160a01b031681565b348015610c1057600080fd5b5061057c6124ea565b348015610c2557600080fd5b5061051b610c34366004614b7a565b6124f9565b348015610c4557600080fd5b5061070f600381565b348015610c5a57600080fd5b5061051b610c69366004614bfc565b61253a565b348015610c7a57600080fd5b5061057c610c89366004614b5f565b6125f1565b348015610c9a57600080fd5b5061051b610ca936600461501e565b612707565b348015610cba57600080fd5b5061051b610cc9366004614bdf565b612716565b348015610cda57600080fd5b5061051b610ce9366004614dba565b612786565b61051b610cfc3660046150d3565b61280f565b348015610d0d57600080fd5b50610d16600181565b60405161ffff9091168152602001610549565b348015610d3557600080fd5b506105c97f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd781565b348015610d6957600080fd5b5061051b610d78366004615188565b61281e565b348015610d8957600080fd5b5061051b610d98366004614bdf565b612856565b348015610da957600080fd5b5061062e610db8366004614bdf565b601c6020526000908152604090205481565b348015610dd657600080fd5b506018546105c9906001600160a01b031681565b348015610df657600080fd5b5061070f600181565b348015610e0b57600080fd5b5061070f600781565b348015610e2057600080fd5b5061057c610e2f366004614b7a565b6128ac565b348015610e4057600080fd5b5061051b610e4f3660046151f3565b6128f6565b348015610e6057600080fd5b5061051b610e6f36600461525e565b612a2d565b348015610e8057600080fd5b5061062e610e8f366004614bdf565b601f6020526000908152604090205481565b348015610ead57600080fd5b5061062e60155481565b348015610ec357600080fd5b5061051b610ed2366004614bfc565b612ac2565b61051b610ee5366004614a36565b612b72565b348015610ef657600080fd5b5061051b610f053660046152cc565b612d88565b348015610f1657600080fd5b5061051b610f25366004614bb3565b612e3a565b348015610f3657600080fd5b5061062e601b5481565b348015610f4c57600080fd5b5061062e7f0000000000000000000000000000000000000000000000000000000002625a0081565b348015610f8057600080fd5b5061053d610f8f366004615308565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b348015610fc957600080fd5b5061070f600581565b348015610fde57600080fd5b5061062e60195481565b348015610ff457600080fd5b5061062e601a5481565b34801561100a57600080fd5b5061051b611019366004614dba565b612e9f565b34801561102a57600080fd5b5061051b611039366004614b7a565b612ef9565b34801561104a57600080fd5b50610811611059366004615341565b612f3a565b34801561106a57600080fd5b5061051b611079366004614bdf565b612f68565b34801561108a57600080fd5b5061057c6110993660046153ba565b612fde565b3480156110aa57600080fd5b5061062e6110b9366004614b5f565b60096020526000908152604090205481565b337f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b0316146111485760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff86166000908152600160205260408120805461116690615407565b80601f016020809104026020016040519081016040528092919081815260200182805461119290615407565b80156111df5780601f106111b4576101008083540402835291602001916111df565b820191906000526020600020905b8154815290600101906020018083116111c257829003601f168201915b505050505090508051868690501480156111fa575060008151115b80156112225750805160208201206040516112189088908890615441565b6040518091039020145b61127d5760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b606482015260840161113f565b6112f38787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061309192505050565b50505050505050565b60006001600160e01b03198216158061131957506113198261310a565b92915050565b336000908152601e602052604090205461133c811515600661312f565b336000908152601e60209081526040808320839055601f90915281208054839290611368908490615467565b9091555050604051600090339083908381818185875af1925050503d80600081146113af576040519150601f19603f3d011682016040523d82523d6000602084013e6113b4565b606091505b50509050806113fc5760405162461bcd60e51b81526020600482015260146024820152732330b4b632b2103a379039b2b7321022ba3432b960611b604482015260640161113f565b60405182815233907fa6183a81b1ce4e0d90156f6ec9b6f2d13c204d11884302b40b47bb456fb59156906020015b60405180910390a25050565b6060600b805461144590615407565b80601f016020809104026020016040519081016040528092919081815260200182805461147190615407565b80156114be5780601f10611493576101008083540402835291602001916114be565b820191906000526020600020905b8154815290600101906020018083116114a157829003601f168201915b5050505050905090565b6114d0613152565b6040516307e0db1760e01b815261ffff821660048201527f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b0316906307e0db17906024015b600060405180830381600087803b15801561153657600080fd5b505af115801561154a573d6000803e3d6000fd5b5050505050565b600061155c826131ac565b506000908152600f60205260409020546001600160a01b031690565b600061158382611d56565b9050806001600160a01b0316836001600160a01b0316036115f05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161113f565b336001600160a01b038216148061160c575061160c8133610f8f565b61167e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000606482015260840161113f565b61168883836131fc565b505050565b611695613152565b600081116116f15760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b606482015260840161113f565b60078190556040518181527ffebbc4f8bb9ec2313950c718d43123124b15778efda4c1f1d529de2995b4f34d906020015b60405180910390a150565b611735613152565b61ffff909116600090815260036020526040902055565b611754613152565b6040516310ddb13760e01b815261ffff821660048201527f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b0316906310ddb1379060240161151c565b6117ac61326a565b6015546016546117df7f0000000000000000000000000000000000000000000000000000000002625a008310600261312f565b6117ed81341015600361312f565b6015600081546117fc9061547a565b9190508190555080601960008282546118159190615467565b90915550611825905033836132c3565b6040805182815260006020820181905291849133917faf10eb5876c114d027970b3131ea6479da41c88b7d3ba0d093aea9a4126444eb910160405180910390a450506118716001600655565b565b61187b6132dd565b61188361326a565b601954611893811515600661312f565b60006019819055601a805483928392916118ae908490615467565b90915550506018546040516001600160a01b0390911690600090829084908381818185875af1925050503d8060008114611904576040519150601f19603f3d011682016040523d82523d6000602084013e611909565b606091505b50509050806119515760405162461bcd60e51b81526020600482015260146024820152732330b4b632b2103a379039b2b7321022ba3432b960611b604482015260640161113f565b816001600160a01b03167f582c87414358df39212a275853c71633d2dc65d15ae92cc5718e7438766bea768460405161198c91815260200190565b60405180910390a2505050506118716001600655565b6119ad335b826132f6565b6119c95760405162461bcd60e51b815260040161113f90615493565b611688838383613374565b6000803063f235364188886119e8896134e5565b88886040518663ffffffff1660e01b8152600401611a0a95949392919061551b565b6040805180830381865afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190615572565b915091509550959350505050565b6000611a6383612113565b8210611ac55760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161113f565b506001600160a01b03919091166000908152601160209081526040808320938352929052205490565b61ffff831660009081526001602052604081208054829190611b0f90615407565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3b90615407565b8015611b885780601f10611b5d57610100808354040283529160200191611b88565b820191906000526020600020905b815481529060010190602001808311611b6b57829003601f168201915b505050505090508383604051611b9f929190615441565b60405180910390208180519060200120149150509392505050565b6116888383836040518060200160405280600081525061281e565b611bdd613152565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd716906342d65a8d90611c2d908690869086906004016155bf565b600060405180830381600087803b158015611c4757600080fd5b505af11580156112f3573d6000803e3d6000fd5b6000611c6660135490565b8210611cc95760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161113f565b60138281548110611cdc57611cdc6155dd565b90600052602060002001549050919050565b6112f3878787611cfd886134e5565b878787613530565b611d0d613152565b611d1d611388821115600861312f565b601b805490829055604051829082907f5520877bcd003e98f39712fa0194b5172c7c1a2f2ec8a1a9deb2b5a79c2525e890600090a35050565b6000818152600d60205260408120546001600160a01b0316806113195760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161113f565b333014611e145760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b606482015260840161113f565b611e8a8686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506135bc92505050565b505050505050565b611e9a613152565b611eaa612710821115600861312f565b60005b82811015611f0d5781601c6000868685818110611ecc57611ecc6155dd565b9050602002016020810190611ee19190614bdf565b6001600160a01b0316815260208101919091526040016000205580611f058161547a565b915050611ead565b508282604051611f1e9291906155f3565b604051908190038120828252907f534f5101174d9c5177797e870102d53e013a9d6b33436ea06de20371c65078e89060200160405180910390a2505050565b611f6561326a565b601554601654611f987f0000000000000000000000000000000000000000000000000000000002625a008310600261312f565b611fa681341015600361312f565b611fd16001600160a01b0384163314801590611fca57506001600160a01b03841615155b600961312f565b601560008154611fe09061547a565b909155506001600160a01b0383166000908152601c602052604081205490811561200a578161200e565b601b545b9050600061271061201f8386615635565b612029919061564c565b90506000612037828661566e565b6001600160a01b0388166000908152601e6020526040812080549293508492909190612064908490615467565b90915550506001600160a01b0387166000908152601d60205260408120805490919061208f9061547a565b9190508190555080601960008282546120a89190615467565b909155506120b8905033876132c3565b60408051828152602081018490526001600160a01b03891691889133917faf10eb5876c114d027970b3131ea6479da41c88b7d3ba0d093aea9a4126444eb910160405180910390a45050505050506121106001600655565b50565b60006001600160a01b03821661217d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b606482015260840161113f565b506001600160a01b03166000908152600e602052604090205490565b6121a1613152565b6118716000613725565b600160205260009081526040902080546121c490615407565b80601f01602080910402602001604051908101604052809291908181526020018280546121f090615407565b801561223d5780601f106122125761010080835404028352916020019161223d565b820191906000526020600020905b81548152906001019060200180831161222057829003601f168201915b505050505081565b61224d613152565b6022546122659060ff1615158215151415600161312f565b6022805460ff19168215159081179091556040517f86f6d3aac457fe4bb989f97e01063ec20dc5442373c5c9a0617a07c7b5362f6b90600090a250565b6122aa61326a565b80516020808301919091206000818152600a90925260409091206002015460ff1661230b5760405162461bcd60e51b81526020600482015260116024820152701b9bc818dc99591a5d1cc81cdd1bdc9959607a1b604482015260640161113f565b60008280602001905181019061232191906156c6565b6000848152600a60205260408120805460019091015492945090925061235d9161ffff8216916201000090046001600160a01b03169085613775565b6000848152600a602052604090206001015490915081116123d25760405162461bcd60e51b815260206004820152602960248201527f6e6f7420656e6f7567682067617320746f2070726f6365737320637265646974604482015268103a3930b739b332b960b91b606482015260840161113f565b81518103612449576000838152600a602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba2339061243c9085815260200190565b60405180910390a16124dd565b604080516080810182526000858152600a6020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b5050506121106001600655565b6060600c805461144590615407565b612501613152565b6017805490829055604051829082907ff87f51c5c0d01564ccf3da315f76df881b0309297d68dde4303ab79a0f1b84cf90600090a35050565b612542613152565b6000811161259d5760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b606482015260840161113f565b61ffff8216600081815260086020908152604091829020849055815192835282018390527f7315f7654d594ead24a30160ed9ba2d23247f543016b918343591e93d7afdb6d91015b60405180910390a15050565b61ffff811660009081526001602052604081208054606092919061261490615407565b80601f016020809104026020016040519081016040528092919081815260200182805461264090615407565b801561268d5780601f106126625761010080835404028352916020019161268d565b820191906000526020600020905b81548152906001019060200180831161267057829003601f168201915b5050505050905080516000036126e55760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f7264000000604482015260640161113f565b6127006000601483516126f8919061566e565b8391906137c1565b9392505050565b6127123383836138ce565b5050565b61271e613152565b6127346001600160a01b0382161515600561312f565b601880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f649c5e3d0ed183894196148e193af316452b0037e77d2ff0fef23b7dc722bed090600090a35050565b61278e613152565b8181306040516020016127a393929190615780565b60408051601f1981840301815291815261ffff85166000908152600160205220906127ce90826157ec565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051612802939291906155bf565b60405180910390a1505050565b6112f387878787878787613530565b61282833836132f6565b6128445760405162461bcd60e51b815260040161113f90615493565b6128508484848461399c565b50505050565b61285e613152565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b90602001611722565b60606128c16128ba836139cf565b600461312f565b60216128cc836139ec565b60206040516020016128e09392919061591e565b6040516020818303038152906040529050919050565b6128fe613152565b6022546129109060ff1615600161312f565b60006021805461291f90615407565b80601f016020809104026020016040519081016040528092919081815260200182805461294b90615407565b80156129985780601f1061296d57610100808354040283529160200191612998565b820191906000526020600020905b81548152906001019060200180831161297b57829003601f168201915b505050505090508484602191826129b0929190615951565b5060206129be838583615951565b5084846040516129cf929190615441565b6040518091039020816040516129e59190615a10565b60405180910390207fc354b4e8393ca297df0d60baaffdd112d7eaa0382a111cc8693009e8f404d9398585604051612a1e929190615a2c565b60405180910390a35050505050565b612a35613152565b6040516332fb62e760e21b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7169063cbed8b9c90612a899088908890889088908890600401615a40565b600060405180830381600087803b158015612aa357600080fd5b505af1158015612ab7573d6000803e3d6000fd5b505050505050505050565b612aca613152565b60008111612b265760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b606482015260840161113f565b61ffff8216600081815260096020908152604091829020849055815192835282018390527fc46df2983228ac2d9754e94a0d565e6671665dc8ad38602bc8e544f0685a29fb91016125e5565b61ffff86166000908152600560205260408082209051612b959088908890615441565b90815260408051602092819003830190206001600160401b03871660009081529252902054905080612c155760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b606482015260840161113f565b808383604051612c26929190615441565b604051809103902014612c855760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b606482015260840161113f565b61ffff87166000908152600560205260408082209051612ca89089908990615441565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252612d40918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506135bc92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e58787878785604051612d77959493929190615a6e565b60405180910390a150505050505050565b612d90613152565b60008111612dd85760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b604482015260640161113f565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001612802565b612e42613152565b612e52612710821115600861312f565b6001600160a01b0382166000818152601c602052604090819020839055517f081217f104a9c8ce8b5570732f898968cb602b62d54965af794344e689a625909061142a9084815260200190565b612ea7613152565b61ffff83166000908152600160205260409020612ec5828483615951565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab838383604051612802939291906155bf565b612f01613152565b6016805490829055604051829082907fd8f648a37e4afe1c401d97caaa06358d2e2725ac008214ce9f5497991e65439690600090a35050565b600080612f4a8787878787613a7e565b6017549193509150612f5c9083615467565b91509550959350505050565b612f70613152565b6001600160a01b038116612fd55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161113f565b61211081613725565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b03169063f5ecbdbc90608401600060405180830381865afa15801561305e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130869190810190615aa9565b90505b949350505050565b6000806130f45a60966366ad5c8a60e01b898989896040516024016130b99493929190615add565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190613b49565b9150915081611e8a57611e8a8686868685613bd3565b60006001600160e01b0319821663780e9d6360e01b1480611319575061131982613c70565b81612712576040516302a9557160e61b815260ff8216600482015260240161113f565b6000546001600160a01b031633146118715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161113f565b6131b5816139cf565b6121105760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604482015260640161113f565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061323182611d56565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6002600654036132bc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161113f565b6002600655565b612712828260405180602001604052806000815250613c8d565b601854611871906001600160a01b03163314600761312f565b60008061330283611d56565b9050806001600160a01b0316846001600160a01b0316148061334957506001600160a01b0380821660009081526010602090815260408083209388168352929052205460ff165b806130895750836001600160a01b031661336284611551565b6001600160a01b031614949350505050565b826001600160a01b031661338782611d56565b6001600160a01b0316146133ad5760405162461bcd60e51b815260040161113f90615b1b565b6001600160a01b03821661340f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161113f565b61341c8383836001613cc0565b826001600160a01b031661342f82611d56565b6001600160a01b0316146134555760405162461bcd60e51b815260040161113f90615b1b565b6000818152600f6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600e8552838620805460001901905590871680865283862080546001019055868652600d90945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061351f5761351f6155dd565b602090810291909101015292915050565b601754600061353f823461566e565b905081601960008282546135539190615467565b9091555061356990508989898989898988613ccc565b8761ffff16896001600160a01b03167f81124ef096134d3d08199ac5bc8e55569b17dcbe54f085c78b63a8da7f789bac846040516135a991815260200190565b60405180910390a3505050505050505050565b600080828060200190518101906135d391906156c6565b6014820151919350915060006135eb88838386613775565b905082518110156136bf5784516020808701919091206040805160808101825261ffff808d1682526001600160a01b038088168387019081528385018881526001606086018181526000898152600a909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad7906136b59083908990615b60565b60405180910390a1505b816001600160a01b0316876040516136d79190615a10565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d990265866040516137139190615b79565b60405180910390a45050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000825b8251811015613086576007545a10613086576137af86868584815181106137a2576137a26155dd565b6020026020010151613ea1565b806137b98161547a565b915050613779565b6060816137cf81601f615467565b101561380e5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b604482015260640161113f565b6138188284615467565b8451101561385c5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b604482015260640161113f565b60608215801561387b57604051915060008252602082016040526138c5565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156138b457805183526020928301920161389c565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b03160361392f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161113f565b6001600160a01b03838116600081815260106020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6139a7848484613374565b6139b384848484613f01565b6128505760405162461bcd60e51b815260040161113f90615b8c565b6000908152600d60205260409020546001600160a01b0316151590565b606060006139f983613fff565b60010190506000816001600160401b03811115613a1857613a18614c59565b6040519080825280601f01601f191660200182016040528015613a42576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084613a4c57509392505050565b60008060008686604051602001613a96929190615bde565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd716906340a7bb1090613afa908b90309086908b908b90600401615c0c565b6040805180830381865afa158015613b16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b3a9190615572565b92509250509550959350505050565b6000606060008060008661ffff166001600160401b03811115613b6e57613b6e614c59565b6040519080825280601f01601f191660200182016040528015613b98576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613bba578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff16815260200190815260200160002085604051613c049190615a10565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c90613c619087908790879087908790615c54565b60405180910390a15050505050565b60006001600160e01b0319821615806113195750611319826140d7565b613c978383614117565b613ca46000848484613f01565b6116885760405162461bcd60e51b815260040161113f90615b8c565b61285084848484614292565b6000855111613d135760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b604482015260640161113f565b845160011480613d37575061ffff8716600090815260086020526040902054855111155b613d8e5760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b606482015260840161113f565b60005b8551811015613dd157613dbf898989898581518110613db257613db26155dd565b60200260200101516143bf565b80613dc98161547a565b915050613d91565b5060008686604051602001613de7929190615bde565b6040516020818303038152906040529050613e2c886001858951600960008e61ffff1661ffff16815260200190815260200160002054613e279190615635565b6144aa565b613e3a888287878787614589565b86604051613e489190615a10565b6040518091039020896001600160a01b03168961ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a89604051613e8e9190615b79565b60405180910390a4505050505050505050565b613eaa816139cf565b1580613ed65750613eba816139cf565b8015613ed6575030613ecb82611d56565b6001600160a01b0316145b613edf57600080fd5b613ee8816139cf565b613ef65761168882826132c3565b611688308383613374565b60006001600160a01b0384163b15613ff757604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613f45903390899088908890600401615ca6565b6020604051808303816000875af1925050508015613f80575060408051601f3d908101601f19168201909252613f7d91810190615ce3565b60015b613fdd573d808015613fae576040519150601f19603f3d011682016040523d82523d6000602084013e613fb3565b606091505b508051600003613fd55760405162461bcd60e51b815260040161113f90615b8c565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613089565b506001613089565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061403e5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061406a576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061408857662386f26fc10000830492506010015b6305f5e10083106140a0576305f5e100830492506008015b61271083106140b457612710830492506004015b606483106140c6576064830492506002015b600a83106113195760010192915050565b60006001600160e01b031982166380ac58cd60e01b148061410857506001600160e01b03198216635b5e139f60e01b145b8061131957506113198261472e565b6001600160a01b03821661416d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161113f565b614176816139cf565b156141c35760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161113f565b6141d1600083836001613cc0565b6141da816139cf565b156142275760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161113f565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60018111156143015760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b606482015260840161113f565b816001600160a01b03851661435d5761435881601380546000838152601460205260408120829055600182018355919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900155565b614380565b836001600160a01b0316856001600160a01b031614614380576143808582614763565b6001600160a01b03841661439c5761439781614800565b61154a565b846001600160a01b0316846001600160a01b03161461154a5761154a84826148af565b6143c8336119a7565b61442b5760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b606482015260840161113f565b836001600160a01b031661443e82611d56565b6001600160a01b03161461449f5760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b606482015260840161113f565b612850843083613374565b60006144b5836148f3565b61ffff8087166000908152600260209081526040808320938916835292905290812054919250906144e7908490615467565b9050600081116145395760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f7420736574000000000000604482015260640161113f565b80821015611e8a5760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f770000000000604482015260640161113f565b61ffff8616600090815260016020526040812080546145a790615407565b80601f01602080910402602001604051908101604052809291908181526020018280546145d390615407565b80156146205780601f106145f557610100808354040283529160200191614620565b820191906000526020600020905b81548152906001019060200180831161460357829003601f168201915b5050505050905080516000036146915760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b606482015260840161113f565b61469c87875161494f565b60405162c5803160e81b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7169063c58031009084906146f3908b9086908c908c908c908c90600401615d00565b6000604051808303818588803b15801561470c57600080fd5b505af1158015614720573d6000803e3d6000fd5b505050505050505050505050565b60006001600160e01b031982166322bac5d960e01b148061131957506301ffc9a760e01b6001600160e01b0319831614611319565b6000600161477084612113565b61477a919061566e565b6000838152601260205260409020549091508082146147cd576001600160a01b03841660009081526011602090815260408083208584528252808320548484528184208190558352601290915290208190555b5060009182526012602090815260408084208490556001600160a01b039094168352601181528383209183525290812055565b6013546000906148129060019061566e565b6000838152601460205260408120546013805493945090928490811061483a5761483a6155dd565b90600052602060002001549050806013838154811061485b5761485b6155dd565b600091825260208083209091019290925582815260149091526040808220849055858252812055601380548061489357614893615d67565b6001900381819060005260206000200160009055905550505050565b60006148ba83612113565b6001600160a01b039093166000908152601160209081526040808320868452825280832085905593825260129052919091209190915550565b60006022825110156149475760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d7300000000604482015260640161113f565b506022015190565b61ffff82166000908152600360205260408120549081900361497057506127105b808211156116885760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c61726765604482015260640161113f565b803561ffff811681146149d257600080fd5b919050565b60008083601f8401126149e957600080fd5b5081356001600160401b03811115614a0057600080fd5b602083019150836020828501011115614a1857600080fd5b9250929050565b80356001600160401b03811681146149d257600080fd5b60008060008060008060808789031215614a4f57600080fd5b614a58876149c0565b955060208701356001600160401b0380821115614a7457600080fd5b614a808a838b016149d7565b9097509550859150614a9460408a01614a1f565b94506060890135915080821115614aaa57600080fd5b50614ab789828a016149d7565b979a9699509497509295939492505050565b6001600160e01b03198116811461211057600080fd5b600060208284031215614af157600080fd5b813561270081614ac9565b60005b83811015614b17578181015183820152602001614aff565b50506000910152565b60008151808452614b38816020860160208601614afc565b601f01601f19169290920160200192915050565b6020815260006127006020830184614b20565b600060208284031215614b7157600080fd5b612700826149c0565b600060208284031215614b8c57600080fd5b5035919050565b6001600160a01b038116811461211057600080fd5b80356149d281614b93565b60008060408385031215614bc657600080fd5b8235614bd181614b93565b946020939093013593505050565b600060208284031215614bf157600080fd5b813561270081614b93565b60008060408385031215614c0f57600080fd5b614bd1836149c0565b600080600060608486031215614c2d57600080fd5b8335614c3881614b93565b92506020840135614c4881614b93565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614c9757614c97614c59565b604052919050565b60006001600160401b03821115614cb857614cb8614c59565b50601f01601f191660200190565b600082601f830112614cd757600080fd5b8135614cea614ce582614c9f565b614c6f565b818152846020838601011115614cff57600080fd5b816020850160208301376000918101602001919091529392505050565b803580151581146149d257600080fd5b600080600080600060a08688031215614d4457600080fd5b614d4d866149c0565b945060208601356001600160401b0380821115614d6957600080fd5b614d7589838a01614cc6565b955060408801359450614d8a60608901614d1c565b93506080880135915080821115614da057600080fd5b50614dad88828901614cc6565b9150509295509295909350565b600080600060408486031215614dcf57600080fd5b614dd8846149c0565b925060208401356001600160401b03811115614df357600080fd5b614dff868287016149d7565b9497909650939450505050565b600080600080600080600060e0888a031215614e2757600080fd5b8735614e3281614b93565b9650614e40602089016149c0565b955060408801356001600160401b0380821115614e5c57600080fd5b614e688b838c01614cc6565b965060608a0135955060808a01359150614e8182614b93565b90935060a089013590614e9382614b93565b90925060c08901359080821115614ea957600080fd5b50614eb68a828b01614cc6565b91505092959891949750929550565b600080600060608486031215614eda57600080fd5b614ee3846149c0565b925060208401356001600160401b03811115614efe57600080fd5b614f0a86828701614cc6565b925050614f1960408501614a1f565b90509250925092565b600080600060408486031215614f3757600080fd5b83356001600160401b0380821115614f4e57600080fd5b818601915086601f830112614f6257600080fd5b813581811115614f7157600080fd5b8760208260051b8501011115614f8657600080fd5b6020928301989097509590910135949350505050565b60008060408385031215614faf57600080fd5b614fb8836149c0565b9150614fc6602084016149c0565b90509250929050565b600060208284031215614fe157600080fd5b61270082614d1c565b600060208284031215614ffc57600080fd5b81356001600160401b0381111561501257600080fd5b61308984828501614cc6565b6000806040838503121561503157600080fd5b823561503c81614b93565b9150614fc660208401614d1c565b60006001600160401b0382111561506357615063614c59565b5060051b60200190565b600082601f83011261507e57600080fd5b8135602061508e614ce58361504a565b82815260059290921b840181019181810190868411156150ad57600080fd5b8286015b848110156150c857803583529183019183016150b1565b509695505050505050565b600080600080600080600060e0888a0312156150ee57600080fd5b87356150f981614b93565b9650615107602089016149c0565b955060408801356001600160401b038082111561512357600080fd5b61512f8b838c01614cc6565b965060608a013591508082111561514557600080fd5b6151518b838c0161506d565b955060808a0135915061516382614b93565b81945061517260a08b01614ba8565b935060c08a0135915080821115614ea957600080fd5b6000806000806080858703121561519e57600080fd5b84356151a981614b93565b935060208501356151b981614b93565b92506040850135915060608501356001600160401b038111156151db57600080fd5b6151e787828801614cc6565b91505092959194509250565b6000806000806040858703121561520957600080fd5b84356001600160401b038082111561522057600080fd5b61522c888389016149d7565b9096509450602087013591508082111561524557600080fd5b50615252878288016149d7565b95989497509550505050565b60008060008060006080868803121561527657600080fd5b61527f866149c0565b945061528d602087016149c0565b93506040860135925060608601356001600160401b038111156152af57600080fd5b6152bb888289016149d7565b969995985093965092949392505050565b6000806000606084860312156152e157600080fd5b6152ea846149c0565b92506152f8602085016149c0565b9150604084013590509250925092565b6000806040838503121561531b57600080fd5b823561532681614b93565b9150602083013561533681614b93565b809150509250929050565b600080600080600060a0868803121561535957600080fd5b615362866149c0565b945060208601356001600160401b038082111561537e57600080fd5b61538a89838a01614cc6565b955060408801359150808211156153a057600080fd5b6153ac89838a0161506d565b9450614d8a60608901614d1c565b600080600080608085870312156153d057600080fd5b6153d9856149c0565b93506153e7602086016149c0565b925060408501356153f781614b93565b9396929550929360600135925050565b600181811c9082168061541b57607f821691505b60208210810361543b57634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561131957611319615451565b60006001820161548c5761548c615451565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b600081518084526020808501945080840160005b83811015615510578151875295820195908201906001016154f4565b509495945050505050565b61ffff8616815260a06020820152600061553860a0830187614b20565b828103604084015261554a81876154e0565b9050841515606084015282810360808401526155668185614b20565b98975050505050505050565b6000806040838503121561558557600080fd5b505080516020909101519092909150565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff84168152604060208201526000613086604083018486615596565b634e487b7160e01b600052603260045260246000fd5b60008184825b8581101561562a57813561560c81614b93565b6001600160a01b0316835260209283019291909101906001016155f9565b509095945050505050565b808202811582820484141761131957611319615451565b60008261566957634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561131957611319615451565b600082601f83011261569257600080fd5b81516156a0614ce582614c9f565b8181528460208386010111156156b557600080fd5b613089826020830160208701614afc565b600080604083850312156156d957600080fd5b82516001600160401b03808211156156f057600080fd5b6156fc86838701615681565b935060209150818501518181111561571357600080fd5b85019050601f8101861361572657600080fd5b8051615734614ce58261504a565b81815260059190911b8201830190838101908883111561575357600080fd5b928401925b8284101561577157835182529284019290840190615758565b80955050505050509250929050565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b601f82111561168857600081815260208120601f850160051c810160208610156157cd5750805b601f850160051c820191505b81811015611e8a578281556001016157d9565b81516001600160401b0381111561580557615805614c59565b615819816158138454615407565b846157a6565b602080601f83116001811461584e57600084156158365750858301515b600019600386901b1c1916600185901b178555611e8a565b600085815260208120601f198616915b8281101561587d5788860151825594840194600190910190840161585e565b508582101561589b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600081546158b881615407565b600182811680156158d057600181146158e557615914565b60ff1984168752821515830287019450615914565b8560005260208060002060005b8581101561590b5781548a8201529084019082016158f2565b50505082870194505b5050505092915050565b600061592a82866158ab565b845161593a818360208901614afc565b615946818301866158ab565b979650505050505050565b6001600160401b0383111561596857615968614c59565b61597c836159768354615407565b836157a6565b6000601f8411600181146159b057600085156159985750838201355b600019600387901b1c1916600186901b17835561154a565b600083815260209020601f19861690835b828110156159e157868501358255602094850194600190920191016159c1565b50868210156159fe5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008251615a22818460208701614afc565b9190910192915050565b602081526000613089602083018486615596565b600061ffff808816835280871660208401525084604083015260806060830152615946608083018486615596565b61ffff86168152608060208201526000615a8c608083018688615596565b6001600160401b0394909416604083015250606001529392505050565b600060208284031215615abb57600080fd5b81516001600160401b03811115615ad157600080fd5b61308984828501615681565b61ffff85168152608060208201526000615afa6080830186614b20565b6001600160401b038516604084015282810360608401526159468185614b20565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b8281526040602082015260006130896040830184614b20565b60208152600061270060208301846154e0565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b604081526000615bf16040830185614b20565b8281036020840152615c0381856154e0565b95945050505050565b61ffff861681526001600160a01b038516602082015260a060408201819052600090615c3a90830186614b20565b841515606084015282810360808401526155668185614b20565b61ffff8616815260a060208201526000615c7160a0830187614b20565b6001600160401b03861660408401528281036060840152615c928186614b20565b905082810360808401526155668185614b20565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615cd990830184614b20565b9695505050505050565b600060208284031215615cf557600080fd5b815161270081614ac9565b61ffff8716815260c060208201526000615d1d60c0830188614b20565b8281036040840152615d2f8188614b20565b6001600160a01b0387811660608601528616608085015283810360a08501529050615d5a8185614b20565b9998505050505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220227fbff534a29408eec9ca125e281be5ca2bd975d586367940279a72a9410a4564736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd70000000000000000000000000000000000000000000000000000000002160ec10000000000000000000000000000000000000000000000000000000002625a0000000000000000000000000000000000000000000000000000013e52b9abe00000000000000000000000000000000000000000000000000000009184e72a000000000000000000000000000000bb3c144ccdd0c5d5400a9b4a416c32002110000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _minGasToTransfer (uint256): 100000
Arg [1] : _lzEndpoint (address): 0xb6319cC6c8c27A8F5dAF0dD3DF91EA35C4720dd7
Arg [2] : _startMintId (uint256): 35000001
Arg [3] : _endMintId (uint256): 40000000
Arg [4] : _mintFee (uint256): 350000000000000
Arg [5] : _bridgeFee (uint256): 160000000000000
Arg [6] : _feeCollector (address): 0x00BB3c144ccdd0c5d5400a9B4A416C3200211000
Arg [7] : _referralEarningBips (uint256): 0
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000186a0
Arg [1] : 000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7
Arg [2] : 0000000000000000000000000000000000000000000000000000000002160ec1
Arg [3] : 0000000000000000000000000000000000000000000000000000000002625a00
Arg [4] : 00000000000000000000000000000000000000000000000000013e52b9abe000
Arg [5] : 00000000000000000000000000000000000000000000000000009184e72a0000
Arg [6] : 00000000000000000000000000bb3c144ccdd0c5d5400a9b4a416c3200211000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
121300:23191:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40287:762;;;;;;;;;;-1:-1:-1;40287:762:0;;;;;:::i;:::-;;:::i;:::-;;143602:254;;;;;;;;;;-1:-1:-1;143602:254:0;;;;;:::i;:::-;;:::i;:::-;;;2124:14:1;;2117:22;2099:41;;2087:2;2072:18;143602:254:0;;;;;;;;142643:474;;;;;;;;;;;;;:::i;97168:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;43585:123::-;;;;;;;;;;-1:-1:-1;43585:123:0;;;;;:::i;:::-;;:::i;98680:171::-;;;;;;;;;;-1:-1:-1;98680:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3445:32:1;;;3427:51;;3415:2;3400:18;98680:171:0;3281:203:1;98198:416:0;;;;;;;;;;-1:-1:-1;98198:416:0;;;;;:::i;:::-;;:::i;124847:61::-;;;;;;;;;;-1:-1:-1;124847:61:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;4482:25:1;;;4470:2;4455:18;124847:61:0;4336:177:1;65054:321:0;;;;;;;;;;-1:-1:-1;65054:321:0;;;;;:::i;:::-;;:::i;45510:142::-;;;;;;;;;;-1:-1:-1;45510:142:0;;;;;:::i;:::-;;:::i;43716:129::-;;;;;;;;;;-1:-1:-1;43716:129:0;;;;;:::i;:::-;;:::i;132117:550::-;;;:::i;124544:22::-;;;;;;;;;;;;;;;;115952:113;;;;;;;;;;-1:-1:-1;116040:10:0;:17;115952:113;;124159:44;;;;;;;;;;;;124199:4;124159:44;;141866:577;;;;;;;;;;;;;:::i;122201:48::-;;;;;;;;;;;;122248:1;122201:48;;;;;4947:4:1;4935:17;;;4917:36;;4905:2;4890:18;122201:48:0;4775:184:1;124915:57:0;;;;;;;;;;-1:-1:-1;124915:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;59228:53;;;;;;;;;;-1:-1:-1;59228:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59228:53:0;;;;;;;;;;;5402:6:1;5390:19;;;5372:38;;-1:-1:-1;;;;;5446:32:1;;;5441:2;5426:18;;5419:60;5495:18;;;5488:34;5565:14;5558:22;5553:2;5538:18;;5531:50;5359:3;5344:19;59228:53:0;5149:438:1;99380:301:0;;;;;;;;;;-1:-1:-1;99380:301:0;;;;;:::i;:::-;;:::i;134631:480::-;;;;;;;;;;-1:-1:-1;134631:480:0;;;;;:::i;:::-;;:::i;:::-;;;;8216:25:1;;;8272:2;8257:18;;8250:34;;;;8189:18;134631:480:0;8042:248:1;115620:256:0;;;;;;;;;;-1:-1:-1;115620:256:0;;;;;:::i;:::-;;:::i;124405:36::-;;;;;;;;;;;;;;;45750:250;;;;;;;;;;-1:-1:-1;45750:250:0;;;;;:::i;:::-;;:::i;39829:53::-;;;;;;;;;;-1:-1:-1;39829:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;99752:151;;;;;;;;;;-1:-1:-1;99752:151:0;;;;;:::i;:::-;;:::i;43853:178::-;;;;;;;;;;-1:-1:-1;43853:178:0;;;;;:::i;:::-;;:::i;58918:39::-;;;;;;;;;;;;;;;;59034:56;;;;;;;;;;-1:-1:-1;59034:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;116142:233;;;;;;;;;;-1:-1:-1;116142:233:0;;;;;:::i;:::-;;:::i;136693:548::-;;;;;;:::i;:::-;;:::i;121970:50::-;;;;;;;;;;;;122019:1;121970:50;;51980:85;;;;;;;;;;-1:-1:-1;51980:85:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122082:48;;;;;;;;;;;;122129:1;122082:48;;128027:390;;;;;;;;;;-1:-1:-1;128027:390:0;;;;;:::i;:::-;;:::i;96878:223::-;;;;;;;;;;-1:-1:-1;96878:223:0;;;;;:::i;:::-;;:::i;53202:346::-;;;;;;;;;;-1:-1:-1;53202:346:0;;;;;:::i;:::-;;:::i;129358:428::-;;;;;;;;;;-1:-1:-1;129358:428:0;;;;;:::i;:::-;;:::i;133024:1105::-;;;;;;:::i;:::-;;:::i;96609:207::-;;;;;;;;;;-1:-1:-1;96609:207:0;;;;;:::i;:::-;;:::i;12039:103::-;;;;;;;;;;;;;:::i;39699:51::-;;;;;;;;;;-1:-1:-1;39699:51:0;;;;;:::i;:::-;;:::i;124573:24::-;;;;;;;;;;;;;;;;122373:47;;;;;;;;;;;;122419:1;122373:47;;125144:30;;;;;;;;;;-1:-1:-1;125144:30:0;;;;;;;;39757:65;;;;;;;;;;-1:-1:-1;39757:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;11398:87;;;;;;;;;;-1:-1:-1;11444:7:0;11471:6;-1:-1:-1;;;;;11471:6:0;11398:87;;131144:227;;;;;;;;;;-1:-1:-1;131144:227:0;;;;;:::i;:::-;;:::i;63264:1009::-;;;;;;;;;;-1:-1:-1;63264:1009:0;;;;;:::i;:::-;;:::i;122312:54::-;;;;;;;;;;;;122365:1;122312:54;;124217:57;;;;;;;;;;;;124139:5;124217:57;;39889:23;;;;;;;;;;-1:-1:-1;39889:23:0;;;;-1:-1:-1;;;;;39889:23:0;;;97337:104;;;;;;;;;;;;;:::i;127618:203::-;;;;;;;;;;-1:-1:-1;127618:203:0;;;;;:::i;:::-;;:::i;122027:48::-;;;;;;;;;;;;122074:1;122027:48;;65899:351;;;;;;;;;;-1:-1:-1;65899:351:0;;;;;:::i;:::-;;:::i;44682:330::-;;;;;;;;;;-1:-1:-1;44682:330:0;;;;;:::i;:::-;;:::i;98923:155::-;;;;;;;;;;-1:-1:-1;98923:155:0;;;;;:::i;:::-;;:::i;129981:312::-;;;;;;;;;;-1:-1:-1;129981:312:0;;;;;:::i;:::-;;:::i;44393:281::-;;;;;;;;;;-1:-1:-1;44393:281:0;;;;;:::i;:::-;;:::i;137815:553::-;;;;;;:::i;:::-;;:::i;58681:45::-;;;;;;;;;;;;58725:1;58681:45;;;;;14786:6:1;14774:19;;;14756:38;;14744:2;14729:18;58681:45:0;14612:188:1;39646:46:0;;;;;;;;;;;;;;;99974:279;;;;;;;;;;-1:-1:-1;99974:279:0;;;;;:::i;:::-;;:::i;45020:136::-;;;;;;;;;;-1:-1:-1;45020:136:0;;;;;:::i;:::-;;:::i;124784:56::-;;;;;;;;;;-1:-1:-1;124784:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;124604:27;;;;;;;;;;-1:-1:-1;124604:27:0;;;;-1:-1:-1;;;;;124604:27:0;;;121909:54;;;;;;;;;;;;121962:1;121909:54;;122256:49;;;;;;;;;;;;122304:1;122256:49;;131545:254;;;;;;;;;;-1:-1:-1;131545:254:0;;;;;:::i;:::-;;:::i;130515:441::-;;;;;;;;;;-1:-1:-1;130515:441:0;;;;;:::i;:::-;;:::i;43373:204::-;;;;;;;;;;-1:-1:-1;43373:204:0;;;;;:::i;:::-;;:::i;124979:58::-;;;;;;;;;;-1:-1:-1;124979:58:0;;;;;:::i;:::-;;;;;;;;;;;;;;124491:27;;;;;;;;;;;;;;;;65476:359;;;;;;;;;;-1:-1:-1;65476:359:0;;;;;:::i;:::-;;:::i;53734:767::-;;;;;;:::i;:::-;;:::i;45164:284::-;;;;;;;;;;-1:-1:-1;45164:284:0;;;;;:::i;:::-;;:::i;128717:335::-;;;;;;;;;;-1:-1:-1;128717:335:0;;;;;:::i;:::-;;:::i;124743:34::-;;;;;;;;;;;;;;;;124448;;;;;;;;;;;;;;;99149:164;;;;;;;;;;-1:-1:-1;99149:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;99270:25:0;;;99246:4;99270:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;99149:164;122137:57;;;;;;;;;;;;122193:1;122137:57;;124640:30;;;;;;;;;;;;;;;;124677:31;;;;;;;;;;;;;;;;44178:207;;;;;;;;;;-1:-1:-1;44178:207:0;;;;;:::i;:::-;;:::i;127270:185::-;;;;;;;;;;-1:-1:-1;127270:185:0;;;;;:::i;:::-;;:::i;135565:561::-;;;;;;;;;;-1:-1:-1;135565:561:0;;;;;:::i;:::-;;:::i;12297:201::-;;;;;;;;;;-1:-1:-1;12297:201:0;;;;;:::i;:::-;;:::i;43100:211::-;;;;;;;;;;-1:-1:-1;43100:211:0;;;;;:::i;:::-;;:::i;59097:57::-;;;;;;;;;;-1:-1:-1;59097:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;40287:762;10187:10;40527;-1:-1:-1;;;;;40503:35:0;;40495:78;;;;-1:-1:-1;;;40495:78:0;;19361:2:1;40495:78:0;;;19343:21:1;19400:2;19380:18;;;19373:30;19439:32;19419:18;;;19412:60;19489:18;;40495:78:0;;;;;;;;;40615:32;;;40586:26;40615:32;;;:19;:32;;;;;40586:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40821:13;:20;40799:11;;:18;;:42;:70;;;;;40868:1;40845:13;:20;:24;40799:70;:124;;;;-1:-1:-1;40899:24:0;;;;;;40873:22;;;;40883:11;;;;40873:22;:::i;:::-;;;;;;;;:50;40799:124;40791:175;;;;-1:-1:-1;;;40791:175:0;;20381:2:1;40791:175:0;;;20363:21:1;20420:2;20400:18;;;20393:30;20459:34;20439:18;;;20432:62;-1:-1:-1;;;20510:18:1;;;20503:36;20556:19;;40791:175:0;20179:402:1;40791:175:0;40979:62;40998:11;41011;;40979:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;40979:62:0;;;;;;;;;;;;;;;;;;;;;;41024:6;;-1:-1:-1;40979:62:0;-1:-1:-1;41032:8:0;;;;;;40979:62;;41032:8;;;;40979:62;;;;;;;;;-1:-1:-1;40979:18:0;;-1:-1:-1;;;40979:62:0:i;:::-;40418:631;40287:762;;;;;;:::o;143602:254::-;143730:4;-1:-1:-1;;;;;;143754:41:0;;;;:94;;;143812:36;143836:11;143812:23;:36::i;:::-;143747:101;143602:254;-1:-1:-1;;143602:254:0:o;142643:474::-;10187:10;142696:16;142715:35;;;:21;:35;;;;;;142761:48;142771:13;;;122248:1;142761:9;:48::i;:::-;10187:10;142860:1;142822:35;;;:21;:35;;;;;;;;:39;;;142872:22;:36;;;;;:48;;142912:8;;142860:1;142872:48;;142912:8;;142872:48;:::i;:::-;;;;-1:-1:-1;;142949:47:0;;142934:9;;10187:10;;142983:8;;142934:9;142949:47;142934:9;142949:47;142983:8;10187:10;142949:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;142933:63;;;143015:4;143007:37;;;;-1:-1:-1;;;143007:37:0;;21260:2:1;143007:37:0;;;21242:21:1;21299:2;21279:18;;;21272:30;-1:-1:-1;;;21318:18:1;;;21311:50;21378:18;;143007:37:0;21058:344:1;143007:37:0;143062:47;;4482:25:1;;;10187:10:0;;143062:47;;4470:2:1;4455:18;143062:47:0;;;;;;;;142685:432;;142643:474::o;97168:100::-;97222:13;97255:5;97248:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97168:100;:::o;43585:123::-;11284:13;:11;:13::i;:::-;43665:35:::1;::::0;-1:-1:-1;;;43665:35:0;;14786:6:1;14774:19;;43665:35:0::1;::::0;::::1;14756:38:1::0;43665:10:0::1;-1:-1:-1::0;;;;;43665:25:0::1;::::0;::::1;::::0;14729:18:1;;43665:35:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;43585:123:::0;:::o;98680:171::-;98756:7;98776:23;98791:7;98776:14;:23::i;:::-;-1:-1:-1;98819:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;98819:24:0;;98680:171::o;98198:416::-;98279:13;98295:23;98310:7;98295:14;:23::i;:::-;98279:39;;98343:5;-1:-1:-1;;;;;98337:11:0;:2;-1:-1:-1;;;;;98337:11:0;;98329:57;;;;-1:-1:-1;;;98329:57:0;;21609:2:1;98329:57:0;;;21591:21:1;21648:2;21628:18;;;21621:30;21687:34;21667:18;;;21660:62;-1:-1:-1;;;21738:18:1;;;21731:31;21779:19;;98329:57:0;21407:397:1;98329:57:0;10187:10;-1:-1:-1;;;;;98421:21:0;;;;:62;;-1:-1:-1;98446:37:0;98463:5;10187:10;99149:164;:::i;98446:37::-;98399:173;;;;-1:-1:-1;;;98399:173:0;;22011:2:1;98399:173:0;;;21993:21:1;22050:2;22030:18;;;22023:30;22089:34;22069:18;;;22062:62;22160:31;22140:18;;;22133:59;22209:19;;98399:173:0;21809:425:1;98399:173:0;98585:21;98594:2;98598:7;98585:8;:21::i;:::-;98268:346;98198:416;;:::o;65054:321::-;11284:13;:11;:13::i;:::-;65192:1:::1;65164:25;:29;65156:78;;;::::0;-1:-1:-1;;;65156:78:0;;22441:2:1;65156:78:0::1;::::0;::::1;22423:21:1::0;22480:2;22460:18;;;22453:30;22519:34;22499:18;;;22492:62;-1:-1:-1;;;22570:18:1;;;22563:34;22614:19;;65156:78:0::1;22239:400:1::0;65156:78:0::1;65245:24;:52:::0;;;65313:54:::1;::::0;4482:25:1;;;65313:54:0::1;::::0;4470:2:1;4455:18;65313:54:0::1;;;;;;;;65054:321:::0;:::o;45510:142::-;11284:13;:11;:13::i;:::-;45601:35:::1;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:43;45510:142::o;43716:129::-;11284:13;:11;:13::i;:::-;43799:38:::1;::::0;-1:-1:-1;;;43799:38:0;;14786:6:1;14774:19;;43799:38:0::1;::::0;::::1;14756::1::0;43799:10:0::1;-1:-1:-1::0;;;;;43799:28:0::1;::::0;::::1;::::0;14729:18:1;;43799:38:0::1;14612:188:1::0;132117:550:0;57690:21;:19;:21::i;:::-;132194:12:::1;::::0;132239:7:::1;::::0;132259:58:::1;132281:9;132269:21:::0;::::1;122019:1;132259:9;:58::i;:::-;132328:59;132351:11;132338:9;:24;;122074:1;132328:9;:59::i;:::-;132402:12;;132400:14;;;;;:::i;:::-;;;;;;;;132446:11;132427:15;;:30;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;132470:34:0::1;::::0;-1:-1:-1;10187:10:0;132494:9:::1;132470;:34::i;:::-;132520:139;::::0;;8216:25:1;;;132630:1:0::1;8272:2:1::0;8257:18;;8250:34;;;132630:1:0;132572:9;;10187:10;;132520:139:::1;::::0;8189:18:1;132520:139:0::1;;;;;;;132163:504;;57734:20:::0;57128:1;58254:7;:22;58071:213;57734:20;132117:550::o;141866:577::-;125393:20;:18;:20::i;:::-;57690:21:::1;:19;:21::i;:::-;141971:15:::2;::::0;141997:56:::2;142007:21:::0;;::::2;122248:1;141997:9;:56::i;:::-;142066:23;142119:15;:19:::0;;;142149:16:::2;:35:::0;;142092:16;;;;142149;:35:::2;::::0;142092:16;;142149:35:::2;:::i;:::-;::::0;;;-1:-1:-1;;142221:12:0::2;::::0;142263:55:::2;::::0;-1:-1:-1;;;;;142221:12:0;;::::2;::::0;142197:21:::2;::::0;142221:12;;142298:15;;142197:21;142263:55;142197:21;142263:55;142298:15;142221:12;142263:55:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;142244:74;;;142337:7;142329:40;;;::::0;-1:-1:-1;;;142329:40:0;;21260:2:1;142329:40:0::2;::::0;::::2;21242:21:1::0;21299:2;21279:18;;;21272:30;-1:-1:-1;;;21318:18:1;;;21311:50;21378:18;;142329:40:0::2;21058:344:1::0;142329:40:0::2;142404:13;-1:-1:-1::0;;;;;142385:50:0::2;;142419:15;142385:50;;;;4482:25:1::0;;4470:2;4455:18;;4336:177;142385:50:0::2;;;;;;;;141933:510;;;;57734:20:::1;57128:1:::0;58254:7;:22;58071:213;99380:301;99541:41;10187:10;99560:12;99574:7;99541:18;:41::i;:::-;99533:99;;;;-1:-1:-1;;;99533:99:0;;;;;;;:::i;:::-;99645:28;99655:4;99661:2;99665:7;99645:9;:28::i;134631:480::-;134876:14;;134923:4;:25;134963:11;134989:10;135014:27;135032:8;135014:17;:27::i;:::-;135056:7;135078:14;134923:180;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;134916:187;;;;134631:480;;;;;;;;:::o;115620:256::-;115717:7;115753:23;115770:5;115753:16;:23::i;:::-;115745:5;:31;115737:87;;;;-1:-1:-1;;;115737:87:0;;25105:2:1;115737:87:0;;;25087:21:1;25144:2;25124:18;;;25117:30;25183:34;25163:18;;;25156:62;-1:-1:-1;;;25234:18:1;;;25227:41;25285:19;;115737:87:0;24903:407:1;115737:87:0;-1:-1:-1;;;;;;115842:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;115620:256::o;45750:250::-;45892:32;;;45846:4;45892:32;;;:19;:32;;;;;45863:61;;45846:4;;45892:32;45863:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45980:11;;45970:22;;;;;;;:::i;:::-;;;;;;;;45952:13;45942:24;;;;;;:50;45935:57;;;45750:250;;;;;:::o;99752:151::-;99856:39;99873:4;99879:2;99883:7;99856:39;;;;;;;;;;;;:16;:39::i;43853:178::-;11284:13;:11;:13::i;:::-;43968:55:::1;::::0;-1:-1:-1;;;43968:55:0;;-1:-1:-1;;;;;43968:10:0::1;:29;::::0;::::1;::::0;:55:::1;::::0;43998:11;;44011;;;;43968:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;116142:233:::0;116217:7;116253:30;116040:10;:17;;115952:113;116253:30;116245:5;:38;116237:95;;;;-1:-1:-1;;;116237:95:0;;26119:2:1;116237:95:0;;;26101:21:1;26158:2;26138:18;;;26131:30;26197:34;26177:18;;;26170:62;-1:-1:-1;;;26248:18:1;;;26241:42;26300:19;;116237:95:0;25917:408:1;116237:95:0;116350:10;116361:5;116350:17;;;;;;;;:::i;:::-;;;;;;;;;116343:24;;116142:233;;;:::o;136693:548::-;137007:226;137033:5;137053:11;137079:10;137104:27;137122:8;137104:17;:27::i;:::-;137146:14;137175:18;137208:14;137007:11;:226::i;128027:390::-;11284:13;:11;:13::i;:::-;128118:77:::1;124199:4;128128:19;:36;;122365:1;128118:9;:77::i;:::-;128245:19;::::0;;128275:41;;;;128332:77:::1;::::0;128297:19;;128245;;128332:77:::1;::::0;128206:36:::1;::::0;128332:77:::1;128107:310;128027:390:::0;:::o;96878:223::-;96950:7;101611:16;;;:7;:16;;;;;;-1:-1:-1;;;;;101611:16:0;;97014:56;;;;-1:-1:-1;;;97014:56:0;;26664:2:1;97014:56:0;;;26646:21:1;26703:2;26683:18;;;26676:30;-1:-1:-1;;;26722:18:1;;;26715:54;26786:18;;97014:56:0;26462:348:1;53202:346:0;10187:10;53416:4;53392:29;53384:80;;;;-1:-1:-1;;;53384:80:0;;27017:2:1;53384:80:0;;;26999:21:1;27056:2;27036:18;;;27029:30;27095:34;27075:18;;;27068:62;-1:-1:-1;;;27146:18:1;;;27139:36;27192:19;;53384:80:0;26815:402:1;53384:80:0;53475:65;53497:11;53510;;53475:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53475:65:0;;;;;;;;;;;;;;;;;;;;;;53523:6;;-1:-1:-1;53475:65:0;-1:-1:-1;53531:8:0;;;;;;53475:65;;53531:8;;;;53475:65;;;;;;;;;-1:-1:-1;53475:21:0;;-1:-1:-1;;;53475:65:0:i;:::-;53202:346;;;;;;:::o;129358:428::-;11284:13;:11;:13::i;:::-;129505:75:::1;124139:5;129515:11;:34;;122365:1;129505:9;:75::i;:::-;129596:9;129591:118;129607:20:::0;;::::1;129591:118;;;129686:11;129649:20;:34;129670:9;;129680:1;129670:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;129649:34:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;129649:34:0;:48;129629:3;::::1;::::0;::::1;:::i;:::-;;;;129591:118;;;;129755:9;;129724:54;;;;;;;:::i;:::-;;::::0;;;;::::1;::::0;;4482:25:1;;;129724:54:0;::::1;::::0;4470:2:1;4455:18;129724:54:0::1;;;;;;;129358:428:::0;;;:::o;133024:1105::-;57690:21;:19;:21::i;:::-;133115:12:::1;::::0;133157:7:::1;::::0;133177:58:::1;133199:9;133187:21:::0;::::1;122019:1;133177:9;:58::i;:::-;133246:56;133269:8;133256:9;:21;;122074:1;133246:9;:56::i;:::-;133313:84;-1:-1:-1::0;;;;;133323:24:0;::::1;10187:10:::0;133323:24:::1;::::0;::::1;::::0;:50:::1;;-1:-1:-1::0;;;;;;133351:22:0;::::1;::::0;::::1;133323:50;122419:1;133313:9;:84::i;:::-;133412:12;;133410:14;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;;;133460:30:0;::::1;133437:20;133460:30:::0;;;:20:::1;:30;::::0;;;;;;133529:17;;:80:::1;;133597:12;133529:80;;;133562:19;;133529:80;133501:108:::0;-1:-1:-1;133620:24:0::1;124139:5;133648:28;133501:108:::0;133648:8;:28:::1;:::i;:::-;133647:44;;;;:::i;:::-;133620:71:::0;-1:-1:-1;133702:19:0::1;133724:27;133620:71:::0;133724:8;:27:::1;:::i;:::-;-1:-1:-1::0;;;;;133764:31:0;::::1;;::::0;;;:21:::1;:31;::::0;;;;:51;;133702:49;;-1:-1:-1;133799:16:0;;133764:31;;;:51:::1;::::0;133799:16;;133764:51:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;133828:35:0;::::1;;::::0;;;:25:::1;:35;::::0;;;;133826:37;;133828:35;;;133826:37:::1;::::0;::::1;:::i;:::-;;;;;;;;133895:11;133876:15;;:30;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;133919:34:0::1;::::0;-1:-1:-1;10187:10:0;133943:9:::1;133919;:34::i;:::-;133969:152;::::0;;8216:25:1;;;8272:2;8257:18;;8250:34;;;-1:-1:-1;;;;;133969:152:0;::::1;::::0;134021:9;;10187:10;;133969:152:::1;::::0;8189:18:1;133969:152:0::1;;;;;;;133084:1045;;;;;;57734:20:::0;57128:1;58254:7;:22;58071:213;57734:20;133024:1105;:::o;96609:207::-;96681:7;-1:-1:-1;;;;;96709:19:0;;96701:73;;;;-1:-1:-1;;;96701:73:0;;28709:2:1;96701:73:0;;;28691:21:1;28748:2;28728:18;;;28721:30;28787:34;28767:18;;;28760:62;-1:-1:-1;;;28838:18:1;;;28831:39;28887:19;;96701:73:0;28507:405:1;96701:73:0;-1:-1:-1;;;;;;96792:16:0;;;;;:9;:16;;;;;;;96609:207::o;12039:103::-;11284:13;:11;:13::i;:::-;12104:30:::1;12131:1;12104:18;:30::i;39699:51::-:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;131144:227::-;11284:13;:11;:13::i;:::-;131228:18:::1;::::0;131218:69:::1;::::0;131228:18:::1;;:28;;::::0;::::1;;;;:18:::0;131218:9:::1;:69::i;:::-;131298:18;:27:::0;;-1:-1:-1;;131298:27:0::1;::::0;::::1;;::::0;;::::1;::::0;;;131341:22:::1;::::0;::::1;::::0;-1:-1:-1;;131341:22:0::1;131144:227:::0;:::o;63264:1009::-;57690:21;:19;:21::i;:::-;63374:19;;::::1;::::0;;::::1;::::0;;;;63350:21:::1;63412:28:::0;;;:13:::1;:28:::0;;;;;;;:42:::1;;::::0;::::1;;63404:72;;;::::0;-1:-1:-1;;;63404:72:0;;29119:2:1;63404:72:0::1;::::0;::::1;29101:21:1::0;29158:2;29138:18;;;29131:30;-1:-1:-1;;;29177:18:1;;;29170:47;29234:18;;63404:72:0::1;28917:341:1::0;63404:72:0::1;63492:22;63529:8;63518:37;;;;;;;;;;;;:::i;:::-;63568:14;63597:28:::0;;;:13:::1;:28;::::0;;;;:39;;;63678:34;;::::1;::::0;63489:66;;-1:-1:-1;63568:14:0;;-1:-1:-1;63585:138:0::1;::::0;63597:39:::1;::::0;::::1;::::0;63638:38;;::::1;-1:-1:-1::0;;;;;63638:38:0::1;::::0;63489:66;63585:11:::1;:138::i;:::-;63754:28;::::0;;;:13:::1;:28;::::0;;;;:34:::1;;::::0;63568:155;;-1:-1:-1;63742:46:0;::::1;63734:100;;;::::0;-1:-1:-1;;;63734:100:0;;31020:2:1;63734:100:0::1;::::0;::::1;31002:21:1::0;31059:2;31039:18;;;31032:30;31098:34;31078:18;;;31071:62;-1:-1:-1;;;31149:18:1;;;31142:39;31198:19;;63734:100:0::1;30818:405:1::0;63734:100:0::1;63864:8;:15;63851:9;:28:::0;63847:419:::1;;63959:28;::::0;;;:13:::1;:28;::::0;;;;;63952:35;;-1:-1:-1;;;;;;63952:35:0;;;;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;63952:35:0::1;::::0;;64007:28;::::1;::::0;::::1;::::0;63973:13;4482:25:1;;4470:2;4455:18;;4336:177;64007:28:0::1;;;;;;;;63847:419;;;64144:110;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;64157:28:0;;;:13:::1;:28;::::0;;;;;;:39;;::::1;::::0;;::::1;64144:110:::0;;-1:-1:-1;;;;;64198:38:0;;;::::1;::::0;::::1;64144:110:::0;;::::1;::::0;;;;;;;;;64157:39;64144:110;;;;;;64113:28;;;;;;;;:141;;;;::::1;::::0;;::::1;-1:-1:-1::0;;;;;;64113:141:0;;;;;;::::1;::::0;;;;;;;::::1;::::0;;;;;;::::1;::::0;;;;;64198:38:::1;64113:141:::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;64113:141:0;;::::1;::::0;;;::::1;::::0;;63847:419:::1;63339:934;;;57734:20:::0;57128:1;58254:7;:22;58071:213;97337:104;97393:13;97426:7;97419:14;;;;;:::i;127618:203::-;11284:13;:11;:13::i;:::-;127713:9:::1;::::0;;127733:22;;;;127771:42:::1;::::0;127745:10;;127713:9;;127771:42:::1;::::0;127690:20:::1;::::0;127771:42:::1;127679:142;127618:203:::0;:::o;65899:351::-;11284:13;:11;:13::i;:::-;66051:1:::1;66025:23;:27;66017:74;;;::::0;-1:-1:-1;;;66017:74:0;;31430:2:1;66017:74:0::1;::::0;::::1;31412:21:1::0;31469:2;31449:18;;;31442:30;31508:34;31488:18;;;31481:62;-1:-1:-1;;;31559:18:1;;;31552:32;31601:19;;66017:74:0::1;31228:398:1::0;66017:74:0::1;66102:35;::::0;::::1;;::::0;;;:22:::1;:35;::::0;;;;;;;;:61;;;66179:63;;31803:38:1;;;31857:18;;31850:34;;;66179:63:0::1;::::0;31776:18:1;66179:63:0::1;;;;;;;;65899:351:::0;;:::o;44682:330::-;44806:35;;;44786:17;44806:35;;;:19;:35;;;;;44786:55;;44761:12;;44786:17;44806:35;44786:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44860:4;:11;44875:1;44860:16;44852:58;;;;-1:-1:-1;;;44852:58:0;;32097:2:1;44852:58:0;;;32079:21:1;32136:2;32116:18;;;32109:30;32175:31;32155:18;;;32148:59;32224:18;;44852:58:0;31895:353:1;44852:58:0;44928:31;44939:1;44956:2;44942:4;:11;:16;;;;:::i;:::-;44928:4;;:31;:10;:31::i;:::-;44921:38;44682:330;-1:-1:-1;;;44682:330:0:o;98923:155::-;99018:52;10187:10;99051:8;99061;99018:18;:52::i;:::-;98923:155;;:::o;129981:312::-;11284:13;:11;:13::i;:::-;130059:71:::1;-1:-1:-1::0;;;;;130069:27:0;::::1;::::0;::::1;122193:1;130059:9;:71::i;:::-;130167:12;::::0;;-1:-1:-1;;;;;130190:28:0;;::::1;-1:-1:-1::0;;;;;;130190:28:0;::::1;::::0;::::1;::::0;;;130234:51:::1;::::0;130167:12;::::1;::::0;130190:28;130167:12;;130234:51:::1;::::0;130141:23:::1;::::0;130234:51:::1;130048:245;129981:312:::0;:::o;44393:281::-;11284:13;:11;:13::i;:::-;44565:14:::1;;44589:4;44548:47;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;44548:47:0;;::::1;::::0;;;;;;44510:35:::1;::::0;::::1;;::::0;;;:19:::1;44548:47;44510:35:::0;;;:85:::1;::::0;:35;:85:::1;:::i;:::-;;44611:55;44635:14;44651;;44611:55;;;;;;;;:::i;:::-;;;;;;;;44393:281:::0;;;:::o;137815:553::-;138152:208;138178:5;138198:11;138224:10;138249:9;138273:14;138302:18;138335:14;138152:11;:208::i;99974:279::-;100105:41;10187:10;100138:7;100105:18;:41::i;:::-;100097:99;;;;-1:-1:-1;;;100097:99:0;;;;;;;:::i;:::-;100207:38;100221:4;100227:2;100231:7;100240:4;100207:13;:38::i;:::-;99974:279;;;;:::o;45020:136::-;11284:13;:11;:13::i;:::-;45090:8:::1;:20:::0;;-1:-1:-1;;;;;;45090:20:0::1;-1:-1:-1::0;;;;;45090:20:0;::::1;::::0;;::::1;::::0;;;45126:22:::1;::::0;3427:51:1;;;45126:22:0::1;::::0;3415:2:1;3400:18;45126:22:0::1;3281:203:1::0;131545:254:0;131610:13;131636:51;131646:16;131654:7;131646;:16::i;:::-;122129:1;131636:9;:51::i;:::-;131729:13;131744:25;131761:7;131744:16;:25::i;:::-;131771:18;131712:78;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;131698:93;;131545:254;;;:::o;130515:441::-;11284:13;:11;:13::i;:::-;130672:18:::1;::::0;130661:60:::1;::::0;130672:18:::1;;130671:19;130672:18:::0;130661:9:::1;:60::i;:::-;130732:29;130764:13;130732:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;130804:16;;130788:13;:32;;;;;;;:::i;:::-;-1:-1:-1::0;130831:18:0::1;:35;130852:14:::0;;130831:18;:35:::1;:::i;:::-;;130915:16;;130882:66;;;;;;;:::i;:::-;;;;;;;;130898:15;130882:66;;;;;;:::i;:::-;;;;;;;;;130933:14;;130882:66;;;;;;;:::i;:::-;;;;;;;;130650:306;130515:441:::0;;;;:::o;43373:204::-;11284:13;:11;:13::i;:::-;43507:62:::1;::::0;-1:-1:-1;;;43507:62:0;;-1:-1:-1;;;;;43507:10:0::1;:20;::::0;::::1;::::0;:62:::1;::::0;43528:8;;43538;;43548:11;;43561:7;;;;43507:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;43373:204:::0;;;;;:::o;65476:359::-;11284:13;:11;:13::i;:::-;65631:1:::1;65604:24;:28;65596:76;;;::::0;-1:-1:-1;;;65596:76:0;;38754:2:1;65596:76:0::1;::::0;::::1;38736:21:1::0;38793:2;38773:18;;;38766:30;38832:34;38812:18;;;38805:62;-1:-1:-1;;;38883:18:1;;;38876:33;38926:19;;65596:76:0::1;38552:399:1::0;65596:76:0::1;65683:36;::::0;::::1;;::::0;;;:23:::1;:36;::::0;;;;;;;;:63;;;65762:65;;31803:38:1;;;31857:18;;31850:34;;;65762:65:0::1;::::0;31776:18:1;65762:65:0::1;31631:259:1::0;53734:767:0;53945:27;;;53923:19;53945:27;;;:14;:27;;;;;;:40;;;;53973:11;;;;53945:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;53945:48:0;;;;;;;;;;;;-1:-1:-1;53945:48:0;54004:73;;;;-1:-1:-1;;;54004:73:0;;39158:2:1;54004:73:0;;;39140:21:1;39197:2;39177:18;;;39170:30;39236:34;39216:18;;;39209:62;-1:-1:-1;;;39287:18:1;;;39280:33;39330:19;;54004:73:0;38956:399:1;54004:73:0;54119:11;54106:8;;54096:19;;;;;;;:::i;:::-;;;;;;;;:34;54088:80;;;;-1:-1:-1;;;54088:80:0;;39562:2:1;54088:80:0;;;39544:21:1;39601:2;39581:18;;;39574:30;39640:34;39620:18;;;39613:62;-1:-1:-1;;;39691:18:1;;;39684:31;39732:19;;54088:80:0;39360:397:1;54088:80:0;54216:27;;;54275:1;54216:27;;;:14;:27;;;;;;:40;;;;54244:11;;;;54216:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54216:48:0;;;;;;;;;;;;:61;;;;54346:65;;;;;;;;;;;;;;;;;;;54368:11;;54381;;54346:65;;;;;;54381:11;54346:65;;54381:11;54346:65;;;;;;;;;-1:-1:-1;;54346:65:0;;;;;;;;;;;;;;;;;;;;;;54394:6;;-1:-1:-1;54346:65:0;-1:-1:-1;54402:8:0;;;;;;54346:65;;54402:8;;;;54346:65;;;;;;;;;-1:-1:-1;54346:21:0;;-1:-1:-1;;;54346:65:0:i;:::-;54427:66;54447:11;54460;;54473:6;54481:11;54427:66;;;;;;;;;;:::i;:::-;;;;;;;;53867:634;53734:767;;;;;;:::o;45164:284::-;11284:13;:11;:13::i;:::-;45288:1:::1;45278:7;:11;45270:45;;;::::0;-1:-1:-1;;;45270:45:0;;40462:2:1;45270:45:0::1;::::0;::::1;40444:21:1::0;40501:2;40481:18;;;40474:30;-1:-1:-1;;;40520:18:1;;;40513:51;40581:18;;45270:45:0::1;40260:345:1::0;45270:45:0::1;45326:28;::::0;;::::1;;::::0;;;:15:::1;:28;::::0;;;;;;;:41;;::::1;::::0;;;;;;;;;;:51;;;45393:47;;40833:34:1;;;40883:18;;40876:43;;;;40935:18;;;40928:34;;;45393:47:0::1;::::0;40796:2:1;40781:18;45393:47:0::1;40610:358:1::0;128717:335:0;11284:13;:11;:13::i;:::-;128846:75:::1;124139:5;128856:11;:34;;122365:1;128846:9;:75::i;:::-;-1:-1:-1::0;;;;;128932:30:0;::::1;;::::0;;;:20:::1;:30;::::0;;;;;;:44;;;128992:52;::::1;::::0;::::1;::::0;128965:11;4482:25:1;;4470:2;4455:18;;4336:177;44178:207:0;11284:13;:11;:13::i;:::-;44279:35:::1;::::0;::::1;;::::0;;;:19:::1;:35;::::0;;;;:43:::1;44317:5:::0;;44279:35;:43:::1;:::i;:::-;;44338:39;44355:14;44371:5;;44338:39;;;;;;;;:::i;127270:185::-:0;11284:13;:11;:13::i;:::-;127359:7:::1;::::0;;127377:18;;;;127411:36:::1;::::0;127387:8;;127359:7;;127411:36:::1;::::0;127338:18:::1;::::0;127411:36:::1;127327:128;127270:185:::0;:::o;135565:561::-;135817:17;135836:14;135885:163;135926:11;135952:10;135977:9;136001:7;136023:14;135885:26;:163::i;:::-;136072:9;;135863:185;;-1:-1:-1;135863:185:0;-1:-1:-1;136059:22:0;;135863:185;136059:22;:::i;:::-;;;135565:561;;;;;;;;:::o;12297:201::-;11284:13;:11;:13::i;:::-;-1:-1:-1;;;;;12386:22:0;::::1;12378:73;;;::::0;-1:-1:-1;;;12378:73:0;;42382:2:1;12378:73:0::1;::::0;::::1;42364:21:1::0;42421:2;42401:18;;;42394:30;42460:34;42440:18;;;42433:62;-1:-1:-1;;;42511:18:1;;;42504:36;42557:19;;12378:73:0::1;42180:402:1::0;12378:73:0::1;12462:28;12481:8;12462:18;:28::i;43100:211::-:0;43235:68;;-1:-1:-1;;;43235:68:0;;42824:6:1;42857:15;;;43235:68:0;;;42839:34:1;42909:15;;42889:18;;;42882:43;43284:4:0;42941:18:1;;;42934:60;43010:18;;;43003:34;;;43203:12:0;;43235:10;-1:-1:-1;;;;;43235:20:0;;;;42786:19:1;;43235:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43235:68:0;;;;;;;;;;;;:::i;:::-;43228:75;;43100:211;;;;;;;:::o;52349:514::-;52499:12;52513:19;52536:153;52570:9;52581:3;52609:34;;;52645:11;52658;52671:6;52679:8;52586:102;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;52586:102:0;;;;;;;;;;;;;;-1:-1:-1;;;;;52586:102:0;-1:-1:-1;;;;;;52586:102:0;;;;;;;;;;52544:4;;52536:153;;:33;:153::i;:::-;52498:191;;;;52749:7;52744:112;;52773:71;52793:11;52806;52819:6;52827:8;52837:6;52773:19;:71::i;115312:224::-;115414:4;-1:-1:-1;;;;;;115438:50:0;;-1:-1:-1;;;115438:50:0;;:90;;;115492:36;115516:11;115492:23;:36::i;144347:141::-;144428:7;144423:57;;144444:36;;-1:-1:-1;;;144444:36:0;;4947:4:1;4935:17;;144444:36:0;;;4917::1;4890:18;;144444:36:0;4775:184:1;11563:132:0;11444:7;11471:6;-1:-1:-1;;;;;11471:6:0;10187:10;11627:23;11619:68;;;;-1:-1:-1;;;11619:68:0;;44343:2:1;11619:68:0;;;44325:21:1;;;44362:18;;;44355:30;44421:34;44401:18;;;44394:62;44473:18;;11619:68:0;44141:356:1;108243:135:0;108325:16;108333:7;108325;:16::i;:::-;108317:53;;;;-1:-1:-1;;;108317:53:0;;26664:2:1;108317:53:0;;;26646:21:1;26703:2;26683:18;;;26676:30;-1:-1:-1;;;26722:18:1;;;26715:54;26786:18;;108317:53:0;26462:348:1;107556:174:0;107631:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;107631:29:0;-1:-1:-1;;;;;107631:29:0;;;;;;;;:24;;107685:23;107631:24;107685:14;:23::i;:::-;-1:-1:-1;;;;;107676:46:0;;;;;;;;;;;107556:174;;:::o;57770:293::-;57172:1;57904:7;;:19;57896:63;;;;-1:-1:-1;;;57896:63:0;;44704:2:1;57896:63:0;;;44686:21:1;44743:2;44723:18;;;44716:30;44782:33;44762:18;;;44755:61;44833:18;;57896:63:0;44502:355:1;57896:63:0;57172:1;58037:7;:18;57770:293::o;102849:110::-;102925:26;102935:2;102939:7;102925:26;;;;;;;;;;;;:9;:26::i;144007:127::-;144072:12;;144062:64;;-1:-1:-1;;;;;144072:12:0;10187:10;144072:28;122304:1;144062:9;:64::i;102243:264::-;102336:4;102353:13;102369:23;102384:7;102369:14;:23::i;:::-;102353:39;;102422:5;-1:-1:-1;;;;;102411:16:0;:7;-1:-1:-1;;;;;102411:16:0;;:52;;;-1:-1:-1;;;;;;99270:25:0;;;99246:4;99270:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;102431:32;102411:87;;;;102491:7;-1:-1:-1;;;;;102467:31:0;:20;102479:7;102467:11;:20::i;:::-;-1:-1:-1;;;;;102467:31:0;;102403:96;102243:264;-1:-1:-1;;;;102243:264:0:o;106208:1229::-;106333:4;-1:-1:-1;;;;;106306:31:0;:23;106321:7;106306:14;:23::i;:::-;-1:-1:-1;;;;;106306:31:0;;106298:81;;;;-1:-1:-1;;;106298:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;106398:16:0;;106390:65;;;;-1:-1:-1;;;106390:65:0;;45470:2:1;106390:65:0;;;45452:21:1;45509:2;45489:18;;;45482:30;45548:34;45528:18;;;45521:62;-1:-1:-1;;;45599:18:1;;;45592:34;45643:19;;106390:65:0;45268:400:1;106390:65:0;106468:42;106489:4;106495:2;106499:7;106508:1;106468:20;:42::i;:::-;106640:4;-1:-1:-1;;;;;106613:31:0;:23;106628:7;106613:14;:23::i;:::-;-1:-1:-1;;;;;106613:31:0;;106605:81;;;;-1:-1:-1;;;106605:81:0;;;;;;;:::i;:::-;106758:24;;;;:15;:24;;;;;;;;106751:31;;-1:-1:-1;;;;;;106751:31:0;;;;;;-1:-1:-1;;;;;107234:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;107234:20:0;;;107269:13;;;;;;;;;:18;;106751:31;107269:18;;;107309:16;;;:7;:16;;;;;;:21;;;;;;;;;;107348:27;;106774:7;;107348:27;;;98268:346;98198:416;;:::o;66477:185::-;66589:13;;;66600:1;66589:13;;;;;;;;;66541;;66567:19;;66589:13;;;;;;;;;;;;-1:-1:-1;66589:13:0;66567:35;;66624:7;66613:5;66619:1;66613:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;66649:5;66477:185;-1:-1:-1;;66477:185:0:o;138927:723::-;139232:9;;139211:18;139273:22;139232:9;139273;:22;:::i;:::-;139252:43;;139327:10;139308:15;;:29;;;;;;;:::i;:::-;;;;-1:-1:-1;139350:227:0;;-1:-1:-1;139370:5:0;139390:11;139416:10;139441:9;139465:14;139494:18;139527:14;139556:10;139350:5;:227::i;:::-;139618:11;139595:47;;139611:5;-1:-1:-1;;;;;139595:47:0;;139631:10;139595:47;;;;4482:25:1;;4470:2;4455:18;;4336:177;139595:47:0;;;;;;;;139200:450;;138927:723;;;;;;;:::o;62190:976::-;62432:27;62461:22;62498:8;62487:37;;;;;;;;;;;;:::i;:::-;62628:2;62608:23;;62602:30;62431:93;;-1:-1:-1;62431:93:0;-1:-1:-1;62537:17:0;62672:48;62684:11;62602:30;62537:17;62431:93;62672:11;:48::i;:::-;62655:65;;62747:8;:15;62735:9;:27;62731:347;;;62891:19;;;;;;;;;;62956:53;;;;;;;;;;;;;;-1:-1:-1;;;;;62956:53:0;;;;;;;;;;;;;;;63004:4;62956:53;;;;;;62867:21;62925:28;;;:13;:28;;;;;;;:84;;;;;;;;;;;-1:-1:-1;;;;;;62925:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;62925:84:0;;;;;;;;;;63029:37;;;;;;62891:19;;62901:8;;63029:37;:::i;:::-;;;;;;;;62764:314;62731:347;63138:9;-1:-1:-1;;;;;63095:63:0;63125:11;63095:63;;;;;;:::i;:::-;;;;;;;;63112:11;63095:63;;;63149:8;63095:63;;;;;;:::i;:::-;;;;;;;;62378:788;;;;62190:976;;;;:::o;12658:191::-;12732:16;12751:6;;-1:-1:-1;;;;;12768:17:0;;;-1:-1:-1;;;;;;12768:17:0;;;;;;12801:40;;12751:6;;;;;;;12801:40;;12732:16;12801:40;12721:128;12658:191;:::o;64472:574::-;64594:7;64622:11;64644:263;64655:9;:16;64651:1;:20;64644:263;;;64781:24;;64769:9;:36;64807:5;64765:47;64829:48;64839:11;64852:10;64864:9;64874:1;64864:12;;;;;;;;:::i;:::-;;;;;;;64829:9;:48::i;:::-;64892:3;;;;:::i;:::-;;;;64644:263;;29407:2779;29548:12;29602:7;29586:12;29602:7;29596:2;29586:12;:::i;:::-;:23;;29578:50;;;;-1:-1:-1;;;29578:50:0;;46727:2:1;29578:50:0;;;46709:21:1;46766:2;46746:18;;;46739:30;-1:-1:-1;;;46785:18:1;;;46778:44;46839:18;;29578:50:0;46525:338:1;29578:50:0;29664:16;29673:7;29664:6;:16;:::i;:::-;29647:6;:13;:33;;29639:63;;;;-1:-1:-1;;;29639:63:0;;47070:2:1;29639:63:0;;;47052:21:1;47109:2;47089:18;;;47082:30;-1:-1:-1;;;47128:18:1;;;47121:47;47185:18;;29639:63:0;46868:341:1;29639:63:0;29715:22;29781:15;;29810:1933;;;;31887:4;31881:11;31868:24;;32068:1;32057:9;32050:20;32118:4;32107:9;32103:20;32097:4;32090:34;29774:2365;;29810:1933;29987:4;29981:11;29968:24;;30624:2;30615:7;30611:16;30996:9;30989:17;30983:4;30979:28;30967:9;30956;30952:25;30948:60;31045:7;31041:2;31037:16;31294:6;31280:9;31273:17;31267:4;31263:28;31251:9;31243:6;31239:22;31235:57;31231:70;31073:426;31328:3;31324:2;31321:11;31073:426;;;31470:9;;31459:21;;31370:4;31362:13;;;;31403;31073:426;;;-1:-1:-1;;31519:26:0;;;31723:2;31706:11;-1:-1:-1;;31702:25:0;31696:4;31689:39;-1:-1:-1;29774:2365:0;-1:-1:-1;32169:9:0;29407:2779;-1:-1:-1;;;;29407:2779:0:o;107873:281::-;107994:8;-1:-1:-1;;;;;107985:17:0;:5;-1:-1:-1;;;;;107985:17:0;;107977:55;;;;-1:-1:-1;;;107977:55:0;;47416:2:1;107977:55:0;;;47398:21:1;47455:2;47435:18;;;47428:30;47494:27;47474:18;;;47467:55;47539:18;;107977:55:0;47214:349:1;107977:55:0;-1:-1:-1;;;;;108043:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;108043:46:0;;;;;;;;;;108105:41;;2099::1;;;108105::0;;2072:18:1;108105:41:0;;;;;;;107873:281;;;:::o;101134:270::-;101247:28;101257:4;101263:2;101267:7;101247:9;:28::i;:::-;101294:47;101317:4;101323:2;101327:7;101336:4;101294:22;:47::i;:::-;101286:110;;;;-1:-1:-1;;;101286:110:0;;;;;;;:::i;101948:128::-;102013:4;101611:16;;;:7;:16;;;;;;-1:-1:-1;;;;;101611:16:0;102037:31;;;101948:128::o;92611:716::-;92667:13;92718:14;92735:17;92746:5;92735:10;:17::i;:::-;92755:1;92735:21;92718:38;;92771:20;92805:6;-1:-1:-1;;;;;92794:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92794:18:0;-1:-1:-1;92771:41:0;-1:-1:-1;92936:28:0;;;92952:2;92936:28;92993:288;-1:-1:-1;;93025:5:0;-1:-1:-1;;;93162:2:0;93151:14;;93146:30;93025:5;93133:44;93223:2;93214:11;;;-1:-1:-1;93244:21:0;92993:288;93244:21;-1:-1:-1;93302:6:0;92611:716;-1:-1:-1;;;92611:716:0:o;60111:388::-;60292:14;60308:11;60332:20;60366:10;60378:9;60355:33;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;60355:33:0;;;;;;;;;;-1:-1:-1;;;60406:85:0;;60355:33;-1:-1:-1;;;;;;60406:10:0;:23;;;;:85;;60430:11;;60451:4;;60355:33;;60467:7;;60476:14;;60406:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60399:92;;;;;60111:388;;;;;;;;:::o;47072:1275::-;47234:4;47240:12;47302:15;47328:13;47352:24;47389:8;47379:19;;-1:-1:-1;;;;;47379:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47379:19:0;;47352:46;;47880:1;47854;47820:9;47814:16;47785:4;47774:9;47770:20;47739:1;47704:7;47678:4;47659:247;47647:259;;47971:16;47960:27;;48016:8;48007:7;48004:21;48001:78;;;48056:8;48045:19;;48001:78;48162:7;48149:11;48142:28;48280:7;48277:1;48270:4;48257:11;48253:22;48238:50;48317:8;;;;-1:-1:-1;47072:1275:0;-1:-1:-1;;;;;;47072:1275:0:o;52871:323::-;53095:8;53085:19;;;;;;53034:14;:27;53049:11;53034:27;;;;;;;;;;;;;;;53062:11;53034:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;53034:48:0;;;;;;;;;:70;;;;53120:66;;;;53134:11;;53147;;53075:6;;53168:8;;53178:7;;53120:66;:::i;:::-;;;;;;;;52871:323;;;;;:::o;112448:228::-;112563:4;-1:-1:-1;;;;;;112587:41:0;;;;:81;;;112632:36;112656:11;112632:23;:36::i;103186:285::-;103281:18;103287:2;103291:7;103281:5;:18::i;:::-;103332:53;103363:1;103367:2;103371:7;103380:4;103332:22;:53::i;:::-;103310:153;;;;-1:-1:-1;;;103310:153:0;;;;;;;:::i;143262:272::-;143465:61;143492:4;143498:2;143502:12;143516:9;143465:26;:61::i;140332:1266::-;140706:1;140687:9;:16;:20;140679:52;;;;-1:-1:-1;;;140679:52:0;;49987:2:1;140679:52:0;;;49969:21:1;50026:2;50006:18;;;49999:30;-1:-1:-1;;;50045:18:1;;;50038:49;50104:18;;140679:52:0;49785:343:1;140679:52:0;140764:9;:16;140784:1;140764:21;:97;;;-1:-1:-1;140826:35:0;;;;;;;:22;:35;;;;;;140806:16;;:55;;140764:97;140742:181;;;;-1:-1:-1;;;140742:181:0;;50335:2:1;140742:181:0;;;50317:21:1;50374:2;50354:18;;;50347:30;50413:34;50393:18;;;50386:62;-1:-1:-1;;;50464:18:1;;;50457:32;50506:19;;140742:181:0;50133:398:1;140742:181:0;140941:6;140936:127;140957:9;:16;140953:1;:20;140936:127;;;140995:56;141006:5;141013:11;141026:10;141038:9;141048:1;141038:12;;;;;;;;:::i;:::-;;;;;;;140995:10;:56::i;:::-;140975:3;;;;:::i;:::-;;;;140936:127;;;;141075:20;141109:10;141121:9;141098:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;141075:56;;141144:183;141173:11;58725:1;141232:14;141300:9;:16;141261:23;:36;141285:11;141261:36;;;;;;;;;;;;;;;;:55;;;;:::i;:::-;141144:14;:183::i;:::-;141338:182;141360:11;141386:7;141408:14;141437:18;141470:14;141499:10;141338:7;:182::i;:::-;141568:10;141536:54;;;;;;:::i;:::-;;;;;;;;141561:5;-1:-1:-1;;;;;141536:54:0;141548:11;141536:54;;;141580:9;141536:54;;;;;;:::i;:::-;;;;;;;;140637:961;140332:1266;;;;;;;;:::o;113053:373::-;113161:17;113169:8;113161:7;:17::i;:::-;113160:18;:86;;;;113183:17;113191:8;113183:7;:17::i;:::-;:62;;;;-1:-1:-1;113240:4:0;113204:24;113219:8;113204:14;:24::i;:::-;-1:-1:-1;;;;;113204:41:0;;113183:62;113152:95;;;;;;113263:17;113271:8;113263:7;:17::i;:::-;113258:161;;113297:31;113307:10;113319:8;113297:9;:31::i;113258:161::-;113361:46;113379:4;113386:10;113398:8;113361:9;:46::i;108942:853::-;109096:4;-1:-1:-1;;;;;109117:13:0;;70090:19;:23;109113:675;;109153:71;;-1:-1:-1;;;109153:71:0;;-1:-1:-1;;;;;109153:36:0;;;;;:71;;10187:10;;109204:4;;109210:7;;109219:4;;109153:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109153:71:0;;;;;;;;-1:-1:-1;;109153:71:0;;;;;;;;;;;;:::i;:::-;;;109149:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109394:6;:13;109411:1;109394:18;109390:328;;109437:60;;-1:-1:-1;;;109437:60:0;;;;;;;:::i;109390:328::-;109668:6;109662:13;109653:6;109649:2;109645:15;109638:38;109149:584;-1:-1:-1;;;;;;109275:51:0;-1:-1:-1;;;109275:51:0;;-1:-1:-1;109268:58:0;;109113:675;-1:-1:-1;109772:4:0;109765:11;;88355:948;88408:7;;-1:-1:-1;;;88486:17:0;;88482:106;;-1:-1:-1;;;88524:17:0;;;-1:-1:-1;88570:2:0;88560:12;88482:106;88615:8;88606:5;:17;88602:106;;88653:8;88644:17;;;-1:-1:-1;88690:2:0;88680:12;88602:106;88735:8;88726:5;:17;88722:106;;88773:8;88764:17;;;-1:-1:-1;88810:2:0;88800:12;88722:106;88855:7;88846:5;:16;88842:103;;88892:7;88883:16;;;-1:-1:-1;88928:1:0;88918:11;88842:103;88972:7;88963:5;:16;88959:103;;89009:7;89000:16;;;-1:-1:-1;89045:1:0;89035:11;88959:103;89089:7;89080:5;:16;89076:103;;89126:7;89117:16;;;-1:-1:-1;89162:1:0;89152:11;89076:103;89206:7;89197:5;:16;89193:68;;89244:1;89234:11;89289:6;88355:948;-1:-1:-1;;88355:948:0:o;96240:305::-;96342:4;-1:-1:-1;;;;;;96379:40:0;;-1:-1:-1;;;96379:40:0;;:105;;-1:-1:-1;;;;;;;96436:48:0;;-1:-1:-1;;;96436:48:0;96379:105;:158;;;;96501:36;96525:11;96501:23;:36::i;103807:942::-;-1:-1:-1;;;;;103887:16:0;;103879:61;;;;-1:-1:-1;;;103879:61:0;;51486:2:1;103879:61:0;;;51468:21:1;;;51505:18;;;51498:30;51564:34;51544:18;;;51537:62;51616:18;;103879:61:0;51284:356:1;103879:61:0;103960:16;103968:7;103960;:16::i;:::-;103959:17;103951:58;;;;-1:-1:-1;;;103951:58:0;;51847:2:1;103951:58:0;;;51829:21:1;51886:2;51866:18;;;51859:30;51925;51905:18;;;51898:58;51973:18;;103951:58:0;51645:352:1;103951:58:0;104022:48;104051:1;104055:2;104059:7;104068:1;104022:20;:48::i;:::-;104169:16;104177:7;104169;:16::i;:::-;104168:17;104160:58;;;;-1:-1:-1;;;104160:58:0;;51847:2:1;104160:58:0;;;51829:21:1;51886:2;51866:18;;;51859:30;51925;51905:18;;;51898:58;51973:18;;104160:58:0;51645:352:1;104160:58:0;-1:-1:-1;;;;;104567:13:0;;;;;;:9;:13;;;;;;;;:18;;104584:1;104567:18;;;104609:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;104609:21:0;;;;;104648:33;104617:7;;104567:13;;104648:33;;104567:13;;104648:33;98923:155;;:::o;116449:915::-;116716:1;116704:9;:13;116700:222;;;116847:63;;-1:-1:-1;;;116847:63:0;;52204:2:1;116847:63:0;;;52186:21:1;52243:2;52223:18;;;52216:30;52282:34;52262:18;;;52255:62;-1:-1:-1;;;52333:18:1;;;52326:51;52394:19;;116847:63:0;52002:417:1;116700:222:0;116952:12;-1:-1:-1;;;;;116981:18:0;;116977:187;;117016:40;117048:7;118191:10;:17;;118164:24;;;;:15;:24;;;;;:44;;;118219:24;;;;;;;;;;;;118087:164;117016:40;116977:187;;;117086:2;-1:-1:-1;;;;;117078:10:0;:4;-1:-1:-1;;;;;117078:10:0;;117074:90;;117105:47;117138:4;117144:7;117105:32;:47::i;:::-;-1:-1:-1;;;;;117178:16:0;;117174:183;;117211:45;117248:7;117211:36;:45::i;:::-;117174:183;;;117284:4;-1:-1:-1;;;;;117278:10:0;:2;-1:-1:-1;;;;;117278:10:0;;117274:83;;117305:40;117333:2;117337:7;117305:27;:40::i;112684:361::-;112801:42;10187:10;112820:12;10107:98;112801:42;112793:101;;;;-1:-1:-1;;;112793:101:0;;52626:2:1;112793:101:0;;;52608:21:1;52665:2;52645:18;;;52638:30;52704:34;52684:18;;;52677:62;-1:-1:-1;;;52755:18:1;;;52748:44;52809:19;;112793:101:0;52424:410:1;112793:101:0;112941:5;-1:-1:-1;;;;;112913:33:0;:24;112928:8;112913:14;:24::i;:::-;-1:-1:-1;;;;;112913:33:0;;112905:80;;;;-1:-1:-1;;;112905:80:0;;53041:2:1;112905:80:0;;;53023:21:1;53080:2;53060:18;;;53053:30;53119:34;53099:18;;;53092:62;-1:-1:-1;;;53170:18:1;;;53163:32;53212:19;;112905:80:0;52839:398:1;112905:80:0;112996:41;113006:5;113021:4;113028:8;112996:9;:41::i;41899:420::-;42035:21;42059:28;42072:14;42059:12;:28::i;:::-;42117;;;;42098:16;42117:28;;;:15;:28;;;;;;;;:35;;;;;;;;;;;;42035:52;;-1:-1:-1;42098:16:0;42117:47;;42155:9;;42117:47;:::i;:::-;42098:66;;42197:1;42183:11;:15;42175:54;;;;-1:-1:-1;;;42175:54:0;;53444:2:1;42175:54:0;;;53426:21:1;53483:2;53463:18;;;53456:30;53522:28;53502:18;;;53495:56;53568:18;;42175:54:0;53242:350:1;42175:54:0;42268:11;42248:16;:31;;42240:71;;;;-1:-1:-1;;;42240:71:0;;53799:2:1;42240:71:0;;;53781:21:1;53838:2;53818:18;;;53811:30;53877:29;53857:18;;;53850:57;53924:18;;42240:71:0;53597:351:1;41338:553:0;41561:32;;;41532:26;41561:32;;;:19;:32;;;;;41532:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41612:13;:20;41636:1;41612:25;41604:86;;;;-1:-1:-1;;;41604:86:0;;54155:2:1;41604:86:0;;;54137:21:1;54194:2;54174:18;;;54167:30;54233:34;54213:18;;;54206:62;-1:-1:-1;;;54284:18:1;;;54277:46;54340:19;;41604:86:0;53953:412:1;41604:86:0;41701:47;41719:11;41732:8;:15;41701:17;:47::i;:::-;41759:124;;-1:-1:-1;;;41759:124:0;;-1:-1:-1;;;;;41759:10:0;:15;;;;41782:10;;41759:124;;41794:11;;41807:13;;41822:8;;41832:14;;41848:18;;41868:14;;41759:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41521:370;41338:553;;;;;;:::o;59556:219::-;59658:4;-1:-1:-1;;;;;;59682:45:0;;-1:-1:-1;;;59682:45:0;;:85;;-1:-1:-1;;;;;;;;;;55384:40:0;;;59731:36;55275:157;118878:988;119144:22;119194:1;119169:22;119186:4;119169:16;:22::i;:::-;:26;;;;:::i;:::-;119206:18;119227:26;;;:17;:26;;;;;;119144:51;;-1:-1:-1;119360:28:0;;;119356:328;;-1:-1:-1;;;;;119427:18:0;;119405:19;119427:18;;;:12;:18;;;;;;;;:34;;;;;;;;;119478:30;;;;;;:44;;;119595:30;;:17;:30;;;;;:43;;;119356:328;-1:-1:-1;119780:26:0;;;;:17;:26;;;;;;;;119773:33;;;-1:-1:-1;;;;;119824:18:0;;;;;:12;:18;;;;;:34;;;;;;;119817:41;118878:988::o;120161:1079::-;120439:10;:17;120414:22;;120439:21;;120459:1;;120439:21;:::i;:::-;120471:18;120492:24;;;:15;:24;;;;;;120865:10;:26;;120414:46;;-1:-1:-1;120492:24:0;;120414:46;;120865:26;;;;;;:::i;:::-;;;;;;;;;120843:48;;120929:11;120904:10;120915;120904:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;121009:28;;;:15;:28;;;;;;;:41;;;121181:24;;;;;121174:31;121216:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;120232:1008;;;120161:1079;:::o;117665:221::-;117750:14;117767:20;117784:2;117767:16;:20::i;:::-;-1:-1:-1;;;;;117798:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;117843:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;117665:221:0:o;42327:271::-;42409:13;42468:2;42443:14;:21;:27;;42435:68;;;;-1:-1:-1;;;42435:68:0;;55549:2:1;42435:68:0;;;55531:21:1;55588:2;55568:18;;;55561:30;55627;55607:18;;;55600:58;55675:18;;42435:68:0;55347:352:1;42435:68:0;-1:-1:-1;42576:2:0;42556:23;42550:30;;42327:271::o;42606:389::-;42729:35;;;42705:21;42729:35;;;:22;:35;;;;;;;42779:21;;;42775:125;;-1:-1:-1;39632:5:0;42775:125;42934:16;42918:12;:32;;42910:77;;;;-1:-1:-1;;;42910:77:0;;55906:2:1;42910:77:0;;;55888:21:1;;;55925:18;;;55918:30;55984:34;55964:18;;;55957:62;56036:18;;42910:77:0;55704:356:1;14:159;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:250::-;2236:1;2246:113;2260:6;2257:1;2254:13;2246:113;;;2336:11;;;2330:18;2317:11;;;2310:39;2282:2;2275:10;2246:113;;;-1:-1:-1;;2393:1:1;2375:16;;2368:27;2151:250::o;2406:271::-;2448:3;2486:5;2480:12;2513:6;2508:3;2501:19;2529:76;2598:6;2591:4;2586:3;2582:14;2575:4;2568:5;2564:16;2529:76;:::i;:::-;2659:2;2638:15;-1:-1:-1;;2634:29:1;2625:39;;;;2666:4;2621:50;;2406:271;-1:-1:-1;;2406:271:1:o;2682:220::-;2831:2;2820:9;2813:21;2794:4;2851:45;2892:2;2881:9;2877:18;2869:6;2851:45;:::i;2907:184::-;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3057:28;3075:9;3057:28;:::i;3096:180::-;3155:6;3208:2;3196:9;3187:7;3183:23;3179:32;3176:52;;;3224:1;3221;3214:12;3176:52;-1:-1:-1;3247:23:1;;3096:180;-1:-1:-1;3096:180:1:o;3489:131::-;-1:-1:-1;;;;;3564:31:1;;3554:42;;3544:70;;3610:1;3607;3600:12;3625:134;3693:20;;3722:31;3693:20;3722:31;:::i;3764:315::-;3832:6;3840;3893:2;3881:9;3872:7;3868:23;3864:32;3861:52;;;3909:1;3906;3899:12;3861:52;3948:9;3935:23;3967:31;3992:5;3967:31;:::i;:::-;4017:5;4069:2;4054:18;;;;4041:32;;-1:-1:-1;;;3764:315:1:o;4084:247::-;4143:6;4196:2;4184:9;4175:7;4171:23;4167:32;4164:52;;;4212:1;4209;4202:12;4164:52;4251:9;4238:23;4270:31;4295:5;4270:31;:::i;4518:252::-;4585:6;4593;4646:2;4634:9;4625:7;4621:23;4617:32;4614:52;;;4662:1;4659;4652:12;4614:52;4685:28;4703:9;4685:28;:::i;5592:456::-;5669:6;5677;5685;5738:2;5726:9;5717:7;5713:23;5709:32;5706:52;;;5754:1;5751;5744:12;5706:52;5793:9;5780:23;5812:31;5837:5;5812:31;:::i;:::-;5862:5;-1:-1:-1;5919:2:1;5904:18;;5891:32;5932:33;5891:32;5932:33;:::i;:::-;5592:456;;5984:7;;-1:-1:-1;;;6038:2:1;6023:18;;;;6010:32;;5592:456::o;6053:127::-;6114:10;6109:3;6105:20;6102:1;6095:31;6145:4;6142:1;6135:15;6169:4;6166:1;6159:15;6185:275;6256:2;6250:9;6321:2;6302:13;;-1:-1:-1;;6298:27:1;6286:40;;-1:-1:-1;;;;;6341:34:1;;6377:22;;;6338:62;6335:88;;;6403:18;;:::i;:::-;6439:2;6432:22;6185:275;;-1:-1:-1;6185:275:1:o;6465:186::-;6513:4;-1:-1:-1;;;;;6538:6:1;6535:30;6532:56;;;6568:18;;:::i;:::-;-1:-1:-1;6634:2:1;6613:15;-1:-1:-1;;6609:29:1;6640:4;6605:40;;6465:186::o;6656:462::-;6698:5;6751:3;6744:4;6736:6;6732:17;6728:27;6718:55;;6769:1;6766;6759:12;6718:55;6805:6;6792:20;6836:48;6852:31;6880:2;6852:31;:::i;:::-;6836:48;:::i;:::-;6909:2;6900:7;6893:19;6955:3;6948:4;6943:2;6935:6;6931:15;6927:26;6924:35;6921:55;;;6972:1;6969;6962:12;6921:55;7037:2;7030:4;7022:6;7018:17;7011:4;7002:7;6998:18;6985:55;7085:1;7060:16;;;7078:4;7056:27;7049:38;;;;7064:7;6656:462;-1:-1:-1;;;6656:462:1:o;7123:160::-;7188:20;;7244:13;;7237:21;7227:32;;7217:60;;7273:1;7270;7263:12;7288:749;7397:6;7405;7413;7421;7429;7482:3;7470:9;7461:7;7457:23;7453:33;7450:53;;;7499:1;7496;7489:12;7450:53;7522:28;7540:9;7522:28;:::i;:::-;7512:38;;7601:2;7590:9;7586:18;7573:32;-1:-1:-1;;;;;7665:2:1;7657:6;7654:14;7651:34;;;7681:1;7678;7671:12;7651:34;7704:49;7745:7;7736:6;7725:9;7721:22;7704:49;:::i;:::-;7694:59;;7800:2;7789:9;7785:18;7772:32;7762:42;;7823:35;7854:2;7843:9;7839:18;7823:35;:::i;:::-;7813:45;;7911:3;7900:9;7896:19;7883:33;7867:49;;7941:2;7931:8;7928:16;7925:36;;;7957:1;7954;7947:12;7925:36;;7980:51;8023:7;8012:8;8001:9;7997:24;7980:51;:::i;:::-;7970:61;;;7288:749;;;;;;;;:::o;8295:481::-;8373:6;8381;8389;8442:2;8430:9;8421:7;8417:23;8413:32;8410:52;;;8458:1;8455;8448:12;8410:52;8481:28;8499:9;8481:28;:::i;:::-;8471:38;;8560:2;8549:9;8545:18;8532:32;-1:-1:-1;;;;;8579:6:1;8576:30;8573:50;;;8619:1;8616;8609:12;8573:50;8658:58;8708:7;8699:6;8688:9;8684:22;8658:58;:::i;:::-;8295:481;;8735:8;;-1:-1:-1;8632:84:1;;-1:-1:-1;;;;8295:481:1:o;8781:1108::-;8919:6;8927;8935;8943;8951;8959;8967;9020:3;9008:9;8999:7;8995:23;8991:33;8988:53;;;9037:1;9034;9027:12;8988:53;9076:9;9063:23;9095:31;9120:5;9095:31;:::i;:::-;9145:5;-1:-1:-1;9169:37:1;9202:2;9187:18;;9169:37;:::i;:::-;9159:47;;9257:2;9246:9;9242:18;9229:32;-1:-1:-1;;;;;9321:2:1;9313:6;9310:14;9307:34;;;9337:1;9334;9327:12;9307:34;9360:49;9401:7;9392:6;9381:9;9377:22;9360:49;:::i;:::-;9350:59;;9456:2;9445:9;9441:18;9428:32;9418:42;;9512:3;9501:9;9497:19;9484:33;9469:48;;9526:33;9551:7;9526:33;:::i;:::-;9578:7;;-1:-1:-1;9637:3:1;9622:19;;9609:33;;9651;9609;9651;:::i;:::-;9703:7;;-1:-1:-1;9763:3:1;9748:19;;9735:33;;9780:16;;;9777:36;;;9809:1;9806;9799:12;9777:36;;9832:51;9875:7;9864:8;9853:9;9849:24;9832:51;:::i;:::-;9822:61;;;8781:1108;;;;;;;;;;:::o;9894:464::-;9978:6;9986;9994;10047:2;10035:9;10026:7;10022:23;10018:32;10015:52;;;10063:1;10060;10053:12;10015:52;10086:28;10104:9;10086:28;:::i;:::-;10076:38;;10165:2;10154:9;10150:18;10137:32;-1:-1:-1;;;;;10184:6:1;10181:30;10178:50;;;10224:1;10221;10214:12;10178:50;10247:49;10288:7;10279:6;10268:9;10264:22;10247:49;:::i;:::-;10237:59;;;10315:37;10348:2;10337:9;10333:18;10315:37;:::i;:::-;10305:47;;9894:464;;;;;:::o;10545:689::-;10640:6;10648;10656;10709:2;10697:9;10688:7;10684:23;10680:32;10677:52;;;10725:1;10722;10715:12;10677:52;10765:9;10752:23;-1:-1:-1;;;;;10835:2:1;10827:6;10824:14;10821:34;;;10851:1;10848;10841:12;10821:34;10889:6;10878:9;10874:22;10864:32;;10934:7;10927:4;10923:2;10919:13;10915:27;10905:55;;10956:1;10953;10946:12;10905:55;10996:2;10983:16;11022:2;11014:6;11011:14;11008:34;;;11038:1;11035;11028:12;11008:34;11093:7;11086:4;11076:6;11073:1;11069:14;11065:2;11061:23;11057:34;11054:47;11051:67;;;11114:1;11111;11104:12;11051:67;11145:4;11137:13;;;;11169:6;;-1:-1:-1;11207:20:1;;;;11194:34;;10545:689;-1:-1:-1;;;;10545:689:1:o;11462:256::-;11528:6;11536;11589:2;11577:9;11568:7;11564:23;11560:32;11557:52;;;11605:1;11602;11595:12;11557:52;11628:28;11646:9;11628:28;:::i;:::-;11618:38;;11675:37;11708:2;11697:9;11693:18;11675:37;:::i;:::-;11665:47;;11462:256;;;;;:::o;11723:180::-;11779:6;11832:2;11820:9;11811:7;11807:23;11803:32;11800:52;;;11848:1;11845;11838:12;11800:52;11871:26;11887:9;11871:26;:::i;11908:320::-;11976:6;12029:2;12017:9;12008:7;12004:23;12000:32;11997:52;;;12045:1;12042;12035:12;11997:52;12085:9;12072:23;-1:-1:-1;;;;;12110:6:1;12107:30;12104:50;;;12150:1;12147;12140:12;12104:50;12173:49;12214:7;12205:6;12194:9;12190:22;12173:49;:::i;12233:315::-;12298:6;12306;12359:2;12347:9;12338:7;12334:23;12330:32;12327:52;;;12375:1;12372;12365:12;12327:52;12414:9;12401:23;12433:31;12458:5;12433:31;:::i;:::-;12483:5;-1:-1:-1;12507:35:1;12538:2;12523:18;;12507:35;:::i;12553:183::-;12613:4;-1:-1:-1;;;;;12638:6:1;12635:30;12632:56;;;12668:18;;:::i;:::-;-1:-1:-1;12713:1:1;12709:14;12725:4;12705:25;;12553:183::o;12741:662::-;12795:5;12848:3;12841:4;12833:6;12829:17;12825:27;12815:55;;12866:1;12863;12856:12;12815:55;12902:6;12889:20;12928:4;12952:60;12968:43;13008:2;12968:43;:::i;12952:60::-;13046:15;;;13132:1;13128:10;;;;13116:23;;13112:32;;;13077:12;;;;13156:15;;;13153:35;;;13184:1;13181;13174:12;13153:35;13220:2;13212:6;13208:15;13232:142;13248:6;13243:3;13240:15;13232:142;;;13314:17;;13302:30;;13352:12;;;;13265;;13232:142;;;-1:-1:-1;13392:5:1;12741:662;-1:-1:-1;;;;;;12741:662:1:o;13408:1199::-;13571:6;13579;13587;13595;13603;13611;13619;13672:3;13660:9;13651:7;13647:23;13643:33;13640:53;;;13689:1;13686;13679:12;13640:53;13728:9;13715:23;13747:31;13772:5;13747:31;:::i;:::-;13797:5;-1:-1:-1;13821:37:1;13854:2;13839:18;;13821:37;:::i;:::-;13811:47;;13909:2;13898:9;13894:18;13881:32;-1:-1:-1;;;;;13973:2:1;13965:6;13962:14;13959:34;;;13989:1;13986;13979:12;13959:34;14012:49;14053:7;14044:6;14033:9;14029:22;14012:49;:::i;:::-;14002:59;;14114:2;14103:9;14099:18;14086:32;14070:48;;14143:2;14133:8;14130:16;14127:36;;;14159:1;14156;14149:12;14127:36;14182:63;14237:7;14226:8;14215:9;14211:24;14182:63;:::i;:::-;14172:73;;14297:3;14286:9;14282:19;14269:33;14254:48;;14311:33;14336:7;14311:33;:::i;:::-;14363:7;14353:17;;14389:39;14423:3;14412:9;14408:19;14389:39;:::i;:::-;14379:49;;14481:3;14470:9;14466:19;14453:33;14437:49;;14511:2;14501:8;14498:16;14495:36;;;14527:1;14524;14517:12;15039:665;15134:6;15142;15150;15158;15211:3;15199:9;15190:7;15186:23;15182:33;15179:53;;;15228:1;15225;15218:12;15179:53;15267:9;15254:23;15286:31;15311:5;15286:31;:::i;:::-;15336:5;-1:-1:-1;15393:2:1;15378:18;;15365:32;15406:33;15365:32;15406:33;:::i;:::-;15458:7;-1:-1:-1;15512:2:1;15497:18;;15484:32;;-1:-1:-1;15567:2:1;15552:18;;15539:32;-1:-1:-1;;;;;15583:30:1;;15580:50;;;15626:1;15623;15616:12;15580:50;15649:49;15690:7;15681:6;15670:9;15666:22;15649:49;:::i;:::-;15639:59;;;15039:665;;;;;;;:::o;15709:719::-;15801:6;15809;15817;15825;15878:2;15866:9;15857:7;15853:23;15849:32;15846:52;;;15894:1;15891;15884:12;15846:52;15934:9;15921:23;-1:-1:-1;;;;;16004:2:1;15996:6;15993:14;15990:34;;;16020:1;16017;16010:12;15990:34;16059:58;16109:7;16100:6;16089:9;16085:22;16059:58;:::i;:::-;16136:8;;-1:-1:-1;16033:84:1;-1:-1:-1;16224:2:1;16209:18;;16196:32;;-1:-1:-1;16240:16:1;;;16237:36;;;16269:1;16266;16259:12;16237:36;;16308:60;16360:7;16349:8;16338:9;16334:24;16308:60;:::i;:::-;15709:719;;;;-1:-1:-1;16387:8:1;-1:-1:-1;;;;15709:719:1:o;16433:622::-;16528:6;16536;16544;16552;16560;16613:3;16601:9;16592:7;16588:23;16584:33;16581:53;;;16630:1;16627;16620:12;16581:53;16653:28;16671:9;16653:28;:::i;:::-;16643:38;;16700:37;16733:2;16722:9;16718:18;16700:37;:::i;:::-;16690:47;;16784:2;16773:9;16769:18;16756:32;16746:42;;16839:2;16828:9;16824:18;16811:32;-1:-1:-1;;;;;16858:6:1;16855:30;16852:50;;;16898:1;16895;16888:12;16852:50;16937:58;16987:7;16978:6;16967:9;16963:22;16937:58;:::i;:::-;16433:622;;;;-1:-1:-1;16433:622:1;;-1:-1:-1;17014:8:1;;16911:84;16433:622;-1:-1:-1;;;16433:622:1:o;17060:324::-;17135:6;17143;17151;17204:2;17192:9;17183:7;17179:23;17175:32;17172:52;;;17220:1;17217;17210:12;17172:52;17243:28;17261:9;17243:28;:::i;:::-;17233:38;;17290:37;17323:2;17312:9;17308:18;17290:37;:::i;:::-;17280:47;;17374:2;17363:9;17359:18;17346:32;17336:42;;17060:324;;;;;:::o;17389:388::-;17457:6;17465;17518:2;17506:9;17497:7;17493:23;17489:32;17486:52;;;17534:1;17531;17524:12;17486:52;17573:9;17560:23;17592:31;17617:5;17592:31;:::i;:::-;17642:5;-1:-1:-1;17699:2:1;17684:18;;17671:32;17712:33;17671:32;17712:33;:::i;:::-;17764:7;17754:17;;;17389:388;;;;;:::o;17782:907::-;17916:6;17924;17932;17940;17948;18001:3;17989:9;17980:7;17976:23;17972:33;17969:53;;;18018:1;18015;18008:12;17969:53;18041:28;18059:9;18041:28;:::i;:::-;18031:38;;18120:2;18109:9;18105:18;18092:32;-1:-1:-1;;;;;18184:2:1;18176:6;18173:14;18170:34;;;18200:1;18197;18190:12;18170:34;18223:49;18264:7;18255:6;18244:9;18240:22;18223:49;:::i;:::-;18213:59;;18325:2;18314:9;18310:18;18297:32;18281:48;;18354:2;18344:8;18341:16;18338:36;;;18370:1;18367;18360:12;18338:36;18393:63;18448:7;18437:8;18426:9;18422:24;18393:63;:::i;:::-;18383:73;;18475:35;18506:2;18495:9;18491:18;18475:35;:::i;18694:460::-;18778:6;18786;18794;18802;18855:3;18843:9;18834:7;18830:23;18826:33;18823:53;;;18872:1;18869;18862:12;18823:53;18895:28;18913:9;18895:28;:::i;:::-;18885:38;;18942:37;18975:2;18964:9;18960:18;18942:37;:::i;:::-;18932:47;;19029:2;19018:9;19014:18;19001:32;19042:31;19067:5;19042:31;:::i;:::-;18694:460;;;;-1:-1:-1;19092:5:1;;19144:2;19129:18;19116:32;;-1:-1:-1;;18694:460:1:o;19518:380::-;19597:1;19593:12;;;;19640;;;19661:61;;19715:4;19707:6;19703:17;19693:27;;19661:61;19768:2;19760:6;19757:14;19737:18;19734:38;19731:161;;19814:10;19809:3;19805:20;19802:1;19795:31;19849:4;19846:1;19839:15;19877:4;19874:1;19867:15;19731:161;;19518:380;;;:::o;19903:271::-;20086:6;20078;20073:3;20060:33;20042:3;20112:16;;20137:13;;;20112:16;19903:271;-1:-1:-1;19903:271:1:o;20586:127::-;20647:10;20642:3;20638:20;20635:1;20628:31;20678:4;20675:1;20668:15;20702:4;20699:1;20692:15;20718:125;20783:9;;;20804:10;;;20801:36;;;20817:18;;:::i;22644:135::-;22683:3;22704:17;;;22701:43;;22724:18;;:::i;:::-;-1:-1:-1;22771:1:1;22760:13;;22644:135::o;23045:409::-;23247:2;23229:21;;;23286:2;23266:18;;;23259:30;23325:34;23320:2;23305:18;;23298:62;-1:-1:-1;;;23391:2:1;23376:18;;23369:43;23444:3;23429:19;;23045:409::o;23459:435::-;23512:3;23550:5;23544:12;23577:6;23572:3;23565:19;23603:4;23632:2;23627:3;23623:12;23616:19;;23669:2;23662:5;23658:14;23690:1;23700:169;23714:6;23711:1;23708:13;23700:169;;;23775:13;;23763:26;;23809:12;;;;23844:15;;;;23736:1;23729:9;23700:169;;;-1:-1:-1;23885:3:1;;23459:435;-1:-1:-1;;;;;23459:435:1:o;23899:749::-;24230:6;24222;24218:19;24207:9;24200:38;24274:3;24269:2;24258:9;24254:18;24247:31;24181:4;24301:46;24342:3;24331:9;24327:19;24319:6;24301:46;:::i;:::-;24395:9;24387:6;24383:22;24378:2;24367:9;24363:18;24356:50;24429:44;24466:6;24458;24429:44;:::i;:::-;24415:58;;24523:6;24516:14;24509:22;24504:2;24493:9;24489:18;24482:50;24581:9;24573:6;24569:22;24563:3;24552:9;24548:19;24541:51;24609:33;24635:6;24627;24609:33;:::i;:::-;24601:41;23899:749;-1:-1:-1;;;;;;;;23899:749:1:o;24653:245::-;24732:6;24740;24793:2;24781:9;24772:7;24768:23;24764:32;24761:52;;;24809:1;24806;24799:12;24761:52;-1:-1:-1;;24832:16:1;;24888:2;24873:18;;;24867:25;24832:16;;24867:25;;-1:-1:-1;24653:245:1:o;25315:266::-;25403:6;25398:3;25391:19;25455:6;25448:5;25441:4;25436:3;25432:14;25419:43;-1:-1:-1;25507:1:1;25482:16;;;25500:4;25478:27;;;25471:38;;;;25563:2;25542:15;;;-1:-1:-1;;25538:29:1;25529:39;;;25525:50;;25315:266::o;25586:326::-;25781:6;25773;25769:19;25758:9;25751:38;25825:2;25820;25809:9;25805:18;25798:30;25732:4;25845:61;25902:2;25891:9;25887:18;25879:6;25871;25845:61;:::i;26330:127::-;26391:10;26386:3;26382:20;26379:1;26372:31;26422:4;26419:1;26412:15;26446:4;26443:1;26436:15;27222:620;27393:3;27424;27471:6;27393:3;27505:310;27519:6;27516:1;27513:13;27505:310;;;27594:6;27581:20;27614:31;27639:5;27614:31;:::i;:::-;-1:-1:-1;;;;;27672:31:1;27658:46;;27727:4;27753:14;;;;27790:15;;;;;27700:1;27534:9;27505:310;;;-1:-1:-1;27831:5:1;;27222:620;-1:-1:-1;;;;;27222:620:1:o;27847:168::-;27920:9;;;27951;;27968:15;;;27962:22;;27948:37;27938:71;;27989:18;;:::i;28152:217::-;28192:1;28218;28208:132;;28262:10;28257:3;28253:20;28250:1;28243:31;28297:4;28294:1;28287:15;28325:4;28322:1;28315:15;28208:132;-1:-1:-1;28354:9:1;;28152:217::o;28374:128::-;28441:9;;;28462:11;;;28459:37;;;28476:18;;:::i;29263:441::-;29316:5;29369:3;29362:4;29354:6;29350:17;29346:27;29336:55;;29387:1;29384;29377:12;29336:55;29416:6;29410:13;29447:48;29463:31;29491:2;29463:31;:::i;29447:48::-;29520:2;29511:7;29504:19;29566:3;29559:4;29554:2;29546:6;29542:15;29538:26;29535:35;29532:55;;;29583:1;29580;29573:12;29532:55;29596:77;29670:2;29663:4;29654:7;29650:18;29643:4;29635:6;29631:17;29596:77;:::i;29709:1104::-;29822:6;29830;29883:2;29871:9;29862:7;29858:23;29854:32;29851:52;;;29899:1;29896;29889:12;29851:52;29932:9;29926:16;-1:-1:-1;;;;;30002:2:1;29994:6;29991:14;29988:34;;;30018:1;30015;30008:12;29988:34;30041:60;30093:7;30084:6;30073:9;30069:22;30041:60;:::i;:::-;30031:70;;30120:2;30110:12;;30168:2;30157:9;30153:18;30147:25;30197:2;30187:8;30184:16;30181:36;;;30213:1;30210;30203:12;30181:36;30236:24;;;-1:-1:-1;30291:4:1;30283:13;;30279:27;-1:-1:-1;30269:55:1;;30320:1;30317;30310:12;30269:55;30349:2;30343:9;30372:60;30388:43;30428:2;30388:43;:::i;30372:60::-;30466:15;;;30548:1;30544:10;;;;30536:19;;30532:28;;;30497:12;;;;30572:19;;;30569:39;;;30604:1;30601;30594:12;30569:39;30628:11;;;;30648:135;30664:6;30659:3;30656:15;30648:135;;;30730:10;;30718:23;;30681:12;;;;30761;;;;30648:135;;;30802:5;30792:15;;;;;;;29709:1104;;;;;:::o;32253:360::-;32464:6;32456;32451:3;32438:33;32534:2;32530:15;;;;-1:-1:-1;;32526:53:1;32490:16;;32515:65;;;32604:2;32596:11;;32253:360;-1:-1:-1;32253:360:1:o;32743:544::-;32844:2;32839:3;32836:11;32833:448;;;32880:1;32905:5;32901:2;32894:17;32950:4;32946:2;32936:19;33020:2;33008:10;33004:19;33001:1;32997:27;32991:4;32987:38;33056:4;33044:10;33041:20;33038:47;;;-1:-1:-1;33079:4:1;33038:47;33134:2;33129:3;33125:12;33122:1;33118:20;33112:4;33108:31;33098:41;;33189:82;33207:2;33200:5;33197:13;33189:82;;;33252:17;;;33233:1;33222:13;33189:82;;33463:1348;33587:3;33581:10;-1:-1:-1;;;;;33606:6:1;33603:30;33600:56;;;33636:18;;:::i;:::-;33665:96;33754:6;33714:38;33746:4;33740:11;33714:38;:::i;:::-;33708:4;33665:96;:::i;:::-;33816:4;;33880:2;33869:14;;33897:1;33892:662;;;;34598:1;34615:6;34612:89;;;-1:-1:-1;34667:19:1;;;34661:26;34612:89;-1:-1:-1;;33420:1:1;33416:11;;;33412:24;33408:29;33398:40;33444:1;33440:11;;;33395:57;34714:81;;33862:943;;33892:662;32690:1;32683:14;;;32727:4;32714:18;;-1:-1:-1;;33928:20:1;;;34045:236;34059:7;34056:1;34053:14;34045:236;;;34148:19;;;34142:26;34127:42;;34240:27;;;;34208:1;34196:14;;;;34075:19;;34045:236;;;34049:3;34309:6;34300:7;34297:19;34294:201;;;34370:19;;;34364:26;-1:-1:-1;;34453:1:1;34449:14;;;34465:3;34445:24;34441:37;34437:42;34422:58;34407:74;;34294:201;-1:-1:-1;;;;;34541:1:1;34525:14;;;34521:22;34508:36;;-1:-1:-1;33463:1348:1:o;34816:722::-;34866:3;34907:5;34901:12;34936:36;34962:9;34936:36;:::i;:::-;34991:1;35008:18;;;35035:133;;;;35182:1;35177:355;;;;35001:531;;35035:133;-1:-1:-1;;35068:24:1;;35056:37;;35141:14;;35134:22;35122:35;;35113:45;;;-1:-1:-1;35035:133:1;;35177:355;35208:5;35205:1;35198:16;35237:4;35282:2;35279:1;35269:16;35307:1;35321:165;35335:6;35332:1;35329:13;35321:165;;;35413:14;;35400:11;;;35393:35;35456:16;;;;35350:10;;35321:165;;;35325:3;;;35515:6;35510:3;35506:16;35499:23;;35001:531;;;;;34816:722;;;;:::o;35543:469::-;35764:3;35792:38;35826:3;35818:6;35792:38;:::i;:::-;35859:6;35853:13;35875:65;35933:6;35929:2;35922:4;35914:6;35910:17;35875:65;:::i;:::-;35956:50;35998:6;35994:2;35990:15;35982:6;35956:50;:::i;:::-;35949:57;35543:469;-1:-1:-1;;;;;;;35543:469:1:o;36017:1204::-;-1:-1:-1;;;;;36136:3:1;36133:27;36130:53;;;36163:18;;:::i;:::-;36192:93;36281:3;36241:38;36273:4;36267:11;36241:38;:::i;:::-;36235:4;36192:93;:::i;:::-;36311:1;36336:2;36331:3;36328:11;36353:1;36348:615;;;;37007:1;37024:3;37021:93;;;-1:-1:-1;37080:19:1;;;37067:33;37021:93;-1:-1:-1;;33420:1:1;33416:11;;;33412:24;33408:29;33398:40;33444:1;33440:11;;;33395:57;37127:78;;36321:894;;36348:615;32690:1;32683:14;;;32727:4;32714:18;;-1:-1:-1;;36384:17:1;;;36484:9;36506:229;36520:7;36517:1;36514:14;36506:229;;;36609:19;;;36596:33;36581:49;;36716:4;36701:20;;;;36669:1;36657:14;;;;36536:12;36506:229;;;36510:3;36763;36754:7;36751:16;36748:159;;;36887:1;36883:6;36877:3;36871;36868:1;36864:11;36860:21;36856:34;36852:39;36839:9;36834:3;36830:19;36817:33;36813:79;36805:6;36798:95;36748:159;;;36950:1;36944:3;36941:1;36937:11;36933:19;36927:4;36920:33;36321:894;;36017:1204;;;:::o;37504:289::-;37635:3;37673:6;37667:13;37689:66;37748:6;37743:3;37736:4;37728:6;37724:17;37689:66;:::i;:::-;37771:16;;;;;37504:289;-1:-1:-1;;37504:289:1:o;37798:246::-;37957:2;37946:9;37939:21;37920:4;37977:61;38034:2;38023:9;38019:18;38011:6;38003;37977:61;:::i;38049:498::-;38249:4;38278:6;38323:2;38315:6;38311:15;38300:9;38293:34;38375:2;38367:6;38363:15;38358:2;38347:9;38343:18;38336:43;;38415:6;38410:2;38399:9;38395:18;38388:34;38458:3;38453:2;38442:9;38438:18;38431:31;38479:62;38536:3;38525:9;38521:19;38513:6;38505;38479:62;:::i;39762:493::-;40011:6;40003;39999:19;39988:9;39981:38;40055:3;40050:2;40039:9;40035:18;40028:31;39962:4;40076:62;40133:3;40122:9;40118:19;40110:6;40102;40076:62;:::i;:::-;-1:-1:-1;;;;;40174:31:1;;;;40169:2;40154:18;;40147:59;-1:-1:-1;40237:2:1;40222:18;40215:34;40068:70;39762:493;-1:-1:-1;;;39762:493:1:o;43048:335::-;43127:6;43180:2;43168:9;43159:7;43155:23;43151:32;43148:52;;;43196:1;43193;43186:12;43148:52;43229:9;43223:16;-1:-1:-1;;;;;43254:6:1;43251:30;43248:50;;;43294:1;43291;43284:12;43248:50;43317:60;43369:7;43360:6;43349:9;43345:22;43317:60;:::i;43388:557::-;43645:6;43637;43633:19;43622:9;43615:38;43689:3;43684:2;43673:9;43669:18;43662:31;43596:4;43716:46;43757:3;43746:9;43742:19;43734:6;43716:46;:::i;:::-;-1:-1:-1;;;;;43802:6:1;43798:31;43793:2;43782:9;43778:18;43771:59;43878:9;43870:6;43866:22;43861:2;43850:9;43846:18;43839:50;43906:33;43932:6;43924;43906:33;:::i;44862:401::-;45064:2;45046:21;;;45103:2;45083:18;;;45076:30;45142:34;45137:2;45122:18;;45115:62;-1:-1:-1;;;45208:2:1;45193:18;;45186:35;45253:3;45238:19;;44862:401::o;45673:289::-;45848:6;45837:9;45830:25;45891:2;45886;45875:9;45871:18;45864:30;45811:4;45911:45;45952:2;45941:9;45937:18;45929:6;45911:45;:::i;46259:261::-;46438:2;46427:9;46420:21;46401:4;46458:56;46510:2;46499:9;46495:18;46487:6;46458:56;:::i;47568:414::-;47770:2;47752:21;;;47809:2;47789:18;;;47782:30;47848:34;47843:2;47828:18;;47821:62;-1:-1:-1;;;47914:2:1;47899:18;;47892:48;47972:3;47957:19;;47568:414::o;47987:422::-;48212:2;48201:9;48194:21;48175:4;48238:45;48279:2;48268:9;48264:18;48256:6;48238:45;:::i;:::-;48331:9;48323:6;48319:22;48314:2;48303:9;48299:18;48292:50;48359:44;48396:6;48388;48359:44;:::i;:::-;48351:52;47987:422;-1:-1:-1;;;;;47987:422:1:o;48414:642::-;48695:6;48683:19;;48665:38;;-1:-1:-1;;;;;48739:32:1;;48734:2;48719:18;;48712:60;48759:3;48803:2;48788:18;;48781:31;;;-1:-1:-1;;48835:46:1;;48861:19;;48853:6;48835:46;:::i;:::-;48931:6;48924:14;48917:22;48912:2;48901:9;48897:18;48890:50;48989:9;48981:6;48977:22;48971:3;48960:9;48956:19;48949:51;49017:33;49043:6;49035;49017:33;:::i;49061:719::-;49364:6;49356;49352:19;49341:9;49334:38;49408:3;49403:2;49392:9;49388:18;49381:31;49315:4;49435:46;49476:3;49465:9;49461:19;49453:6;49435:46;:::i;:::-;-1:-1:-1;;;;;49521:6:1;49517:31;49512:2;49501:9;49497:18;49490:59;49597:9;49589:6;49585:22;49580:2;49569:9;49565:18;49558:50;49631:33;49657:6;49649;49631:33;:::i;:::-;49617:47;;49713:9;49705:6;49701:22;49695:3;49684:9;49680:19;49673:51;49741:33;49767:6;49759;49741:33;:::i;50536:489::-;-1:-1:-1;;;;;50805:15:1;;;50787:34;;50857:15;;50852:2;50837:18;;50830:43;50904:2;50889:18;;50882:34;;;50952:3;50947:2;50932:18;;50925:31;;;50730:4;;50973:46;;50999:19;;50991:6;50973:46;:::i;:::-;50965:54;50536:489;-1:-1:-1;;;;;;50536:489:1:o;51030:249::-;51099:6;51152:2;51140:9;51131:7;51127:23;51123:32;51120:52;;;51168:1;51165;51158:12;51120:52;51200:9;51194:16;51219:30;51243:5;51219:30;:::i;54370:840::-;54719:6;54711;54707:19;54696:9;54689:38;54763:3;54758:2;54747:9;54743:18;54736:31;54670:4;54790:46;54831:3;54820:9;54816:19;54808:6;54790:46;:::i;:::-;54884:9;54876:6;54872:22;54867:2;54856:9;54852:18;54845:50;54918:33;54944:6;54936;54918:33;:::i;:::-;-1:-1:-1;;;;;55025:15:1;;;55020:2;55005:18;;54998:43;55078:15;;55072:3;55057:19;;55050:44;55131:22;;;54978:3;55110:19;;55103:51;54904:47;-1:-1:-1;55171:33:1;54904:47;55189:6;55171:33;:::i;:::-;55163:41;54370:840;-1:-1:-1;;;;;;;;;54370:840:1:o;55215:127::-;55276:10;55271:3;55267:20;55264:1;55257:31;55307:4;55304:1;55297:15;55331:4;55328:1;55321:15
Swarm Source
ipfs://227fbff534a29408eec9ca125e281be5ca2bd975d586367940279a72a9410a45
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BASE | 33.14% | $1,795.73 | 0.1578 | $283.38 | |
BSC | 21.81% | $615 | 0.3032 | $186.48 | |
SCROLL | 12.66% | $1,791.53 | 0.0604 | $108.26 | |
LINEA | 10.53% | $1,791.53 | 0.0502 | $90.02 | |
OP | 8.33% | $1,791.24 | 0.0398 | $71.25 | |
POL | 4.32% | $0.218781 | 168.7825 | $36.93 | |
ZKEVM | 3.85% | $1,791.53 | 0.0184 | $32.89 | |
ARBNOVA | 2.84% | $1,791.14 | 0.0136 | $24.32 | |
GNO | 1.74% | $1 | 14.85 | $14.85 | |
CELO | 0.68% | $0.330588 | 17.6 | $5.82 | |
ETH | 0.04% | $1,791.53 | 0.0002 | $0.358306 | |
MANTLE | 0.04% | $0.710424 | 0.458 | $0.325374 | |
AVAX | 0.02% | $22.92 | 0.00798 | $0.182885 |
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.