Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 217 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Send From | 4638912 | 622 days ago | IN | 0.00012125 ETH | 0.00001497 | ||||
| Mint | 4638904 | 622 days ago | IN | 0.0004 ETH | 0.0000049 | ||||
| Send From | 4452931 | 628 days ago | IN | 0.00011525 ETH | 0.00001427 | ||||
| Mint | 4452927 | 628 days ago | IN | 0.0004 ETH | 0.00000468 | ||||
| Send From | 3947985 | 646 days ago | IN | 0.0002742 ETH | 0.00002085 | ||||
| Mint | 3947976 | 646 days ago | IN | 0.0004 ETH | 0.00000704 | ||||
| Send From | 3816792 | 650 days ago | IN | 0.00023268 ETH | 0.00001586 | ||||
| Mint | 3816782 | 650 days ago | IN | 0.0004 ETH | 0.00000519 | ||||
| Send From | 3709948 | 654 days ago | IN | 0.00014671 ETH | 0.00001649 | ||||
| Mint | 3709923 | 654 days ago | IN | 0.0004 ETH | 0.00000536 | ||||
| Send From | 3530490 | 660 days ago | IN | 0.00196141 ETH | 0.00002225 | ||||
| Mint | 3529540 | 660 days ago | IN | 0.0004 ETH | 0.00000737 | ||||
| Send From | 3528031 | 660 days ago | IN | 0.00037059 ETH | 0.00002194 | ||||
| Mint | 3527906 | 660 days ago | IN | 0.0004 ETH | 0.00000745 | ||||
| Send From | 3476571 | 662 days ago | IN | 0.00040074 ETH | 0.00001517 | ||||
| Mint | 3476558 | 662 days ago | IN | 0.0004 ETH | 0.00000512 | ||||
| Send From | 3457250 | 663 days ago | IN | 0.00041356 ETH | 0.00001878 | ||||
| Mint | 3457246 | 663 days ago | IN | 0.0004 ETH | 0.00000635 | ||||
| Send From | 3450550 | 663 days ago | IN | 0.00040074 ETH | 0.00001662 | ||||
| Mint | 3450542 | 663 days ago | IN | 0.0004 ETH | 0.00000562 | ||||
| Send From | 3386089 | 665 days ago | IN | 0.00040074 ETH | 0.00002333 | ||||
| Mint | 3386076 | 665 days ago | IN | 0.0004 ETH | 0.00000825 | ||||
| Send From | 3385263 | 665 days ago | IN | 0.00008623 ETH | 0.00002442 | ||||
| Mint | 3385260 | 665 days ago | IN | 0.0004 ETH | 0.00000824 | ||||
| Send From | 3385250 | 665 days ago | IN | 0.00010834 ETH | 0.00002516 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 4638912 | 622 days ago | 0.00012125 ETH | ||||
| 4452931 | 628 days ago | 0.00011525 ETH | ||||
| 3947985 | 646 days ago | 0.0002742 ETH | ||||
| 3816792 | 650 days ago | 0.00023268 ETH | ||||
| 3709948 | 654 days ago | 0.00014671 ETH | ||||
| 3568101 | 659 days ago | 0 ETH | ||||
| 3568101 | 659 days ago | 0 ETH | ||||
| 3530490 | 660 days ago | 0.00196141 ETH | ||||
| 3528031 | 660 days ago | 0.00037059 ETH | ||||
| 3476571 | 662 days ago | 0.00040074 ETH | ||||
| 3457604 | 663 days ago | 0 ETH | ||||
| 3457604 | 663 days ago | 0 ETH | ||||
| 3457250 | 663 days ago | 0.00041356 ETH | ||||
| 3450550 | 663 days ago | 0.00040074 ETH | ||||
| 3386089 | 665 days ago | 0.00040074 ETH | ||||
| 3385263 | 665 days ago | 0.00008623 ETH | ||||
| 3385250 | 665 days ago | 0.00010834 ETH | ||||
| 3385235 | 665 days ago | 0.00041356 ETH | ||||
| 3385221 | 665 days ago | 0.00040074 ETH | ||||
| 2661962 | 696 days ago | 0.00017307 ETH | ||||
| 783581 | 817 days ago | 0 ETH | ||||
| 783581 | 817 days ago | 0 ETH | ||||
| 778599 | 817 days ago | 0 ETH | ||||
| 778599 | 817 days ago | 0 ETH | ||||
| 694730 | 829 days ago | 0.00027914 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Omni
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/**
*Submitted for verification at lineascan.build/ on 2023-08-31
*/
//SPDX-License-Identifier: BUSL-1.1
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(((((&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%(((((((((((((#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@#((((((((((((((((((((@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@(((((((((((((((((((((@@@@@@@&((@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@&((((((((((((((((((((#@@@@@@@(((((((((((#@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@#@@&(((((((((((((((((&@@@@@@&(((((((((((((((((((#@@@@@@@@@@@@@@@
// @@@@@@@@@@@&(((((&@%((((((((((((/@@@@@@@#((((((((((((((((((((#@@@@@@@@@@@@@@@@@@
// @@@@@@@#(((((((((&@%((((((((((@@@@@@(////////////((((((((%@@@@@@@((((((((#@@@@@@
// @@@@@@%((((((((((&@%((((((((//@%////////////////////(@@@@@@@%(((((((((((((#@@@@@
// @@@@@@%((((((((((&@%((((((//////////////////////#@@@@@@@((((((((((((((((((#@@@@@
// @@@@@@%((((((((%@@@%((((////////////////////&@@@@@@@//////(((((((((((((((((@@@@@
// @@@@@@%((((%@@@@@@&/((/////////////////(@@@@@@@%////////////(((((((((((((((@@@@@
// @@@@@@@@@@@@@@#(((((///////////////%@@@@@@@(/////////////////((((((((((((((@@@@@
// @@@@@@@@@@((((((((((///////////&@@@@@@&/////////////////////#/(((((((((((((@@@@@
// @@@@@@%((((((((((((///////////@@@@#////////////////////(@@@@@/(((((((((((((@@@@@
// @@@@@@%(((((((((((////////////@@@//////////////////%@@@@@@&////((((((((((((@@@@@
// @@@@@@%((((((((((/&(//////////@@@//////////////&@@@@@@#///////(((((((((((((@@@@@
// @@@@@@%(((((((@@@@@#//////////@@@/////////(@@@@@@@////////////(((((((((((((@@@@@
// @@@@@@&((%@@@@@@@@@%//////////@@@/////%@@@@@@&///////////////((((((((((((((@@@@@
// @@@@@@@@@@@@%((((@@%((////////@@@#@@@@@@@#/////////////////((((((((((((((((@@@@@
// @@@@@@@@%((((((((@@%((((/////#@@@@@@@/////////////////////%@@((((((((((((((@@@@@
// @@@@@@@((((((((((&@&((((/%@@@@@@&/////////////////////&@@@@@&((((((((((((((@@@@@
// @@@@@@@((((((((((&@@#@@@@@@@#////////////////////(@@@@@@@((((((((((((((((((@@@@@
// @@@@@@@#((((((((%@@@@@@@((((((((/////////////%@@@@@@%(((((((((((((((((((((@@@@@@
// @@@@@@@@@@@&&@@@@@@&((((((((((((((((((((/@@@@@@@((((((((((((((((((((((@@@@@@@@@@
// @@@@@@@@@@@@@@@@#((((((((((((((((((((@@@@@@@(((((((((((((((((((((%@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@#(((((((((((%@@@@@@%(((((((((((((((((((((@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@&(((@@@@@@@(((((((((((((((((((((#@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(((((((((((((((((((((&@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#((((((((((((((@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&(((((%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
pragma solidity ^0.8.0;
// 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);
event CreditStored(bytes32 _hashedPayload, bytes _payload);
event CreditCleared(bytes32 _hashedPayload);
function sendFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
function sendBatchFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
function estimateSendFee(uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
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[]));
if(tokenIds[0]==0){
return;
}
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;
}
}
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);
}
}
}
// OMNI ONFT721
contract Omni is ONFT721 {
uint public fee = 0.00035 ether;
uint public referral_fee = 0.0001 ether;
uint public nextMintId;
uint public maxMintId;
event ReferralUsed(address indexed minter, uint256 tokenId, address referralAddress);
constructor(
uint256 _minGasToTransfer,
address _layerZeroEndpoint,
uint _startMintId,
uint _endMintId) ONFT721("Omni ONFT", "OMNI", _minGasToTransfer, _layerZeroEndpoint) {
nextMintId = _startMintId;
maxMintId = _endMintId;
}
// Referral With Overload Function
function _mintWithReferral(address referralAddress) internal {
require(msg.value >= fee, "Insufficient Ether");
require(nextMintId <= maxMintId, "Minting Error");
uint newId = nextMintId;
nextMintId++;
_safeMint(msg.sender, newId);
if (referralAddress != address(0)) {
emit ReferralUsed(msg.sender, newId, referralAddress);
}
}
function mint() external payable {
_mintWithReferral(address(0));
}
function mint(address referralAddress) external payable {
_mintWithReferral(referralAddress);
}
function estimateGasBridgeFee(uint16 _dstChainId, bool _useZro, bytes memory _adapterParams) public view virtual returns (uint nativeFee, uint zroFee) {
bytes memory payload = abi.encode(msg.sender,0);
return lzEndpoint.estimateFees(_dstChainId, payable(address(this)), payload, _useZro, _adapterParams);
}
function bridgeGas(uint16 _dstChainId, address _zroPaymentAddress, bytes memory _adapterParams) public payable {
_checkGasLimit(_dstChainId, FUNCTION_TYPE_SEND, _adapterParams, dstChainIdToTransferGas[_dstChainId]);
_lzSend(_dstChainId, abi.encode(msg.sender,0), payable(address(this)), _zroPaymentAddress, _adapterParams, msg.value);
}
function tokenURI(uint256 id) public view virtual override returns (string memory){
return string(abi.encodePacked(_baseURI(), Strings.toString(id)));
}
function _baseURI() internal pure override returns (string memory) {
return "https://api.omnitrum.com/api/omni/";
}
function withdraw() public payable onlyOwner {
(bool success, ) = payable(msg.sender).call{
value: address(this).balance
}("");
require(success);
}
function setFee(uint _fee) external onlyOwner {
fee = _fee;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"_minGasToTransfer","type":"uint256"},{"internalType":"address","name":"_layerZeroEndpoint","type":"address"},{"internalType":"uint256","name":"_startMintId","type":"uint256"},{"internalType":"uint256","name":"_endMintId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"}],"name":"CreditCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"CreditStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":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":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"referralAddress","type":"address"}],"name":"ReferralUsed","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":"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":"FUNCTION_TYPE_SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"bridgeGas","outputs":[],"stateMutability":"payable","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":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateGasBridgeFee","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":"_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":"fee","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":"referralAddress","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"referral_fee","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":"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":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"setMinGasToTransferAndStore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setPayloadSizeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_precrime","type":"address"}],"name":"setPrecrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_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":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storedCredits","outputs":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bool","name":"creditsRemain","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
60a060405266013e52b9abe000601155655af3107a40006012553480156200002657600080fd5b5060405162004f2e38038062004f2e8339810160408190526200004991620001a8565b6040518060400160405280600981526020016813db5b9a4813d3919560ba1b815250604051806040016040528060048152602001634f4d4e4960e01b8152508585838383838080620000aa620000a46200015460201b60201c565b62000158565b6001600160a01b0316608052506001600655816200011a5760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b606482015260840160405180910390fd5b50600755600b6200012c83826200029a565b50600c6200013b82826200029a565b5050506013959095555050506014555062000366915050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060008060808587031215620001bf57600080fd5b845160208601519094506001600160a01b0381168114620001df57600080fd5b6040860151606090960151949790965092505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200022057607f821691505b6020821081036200024157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029557600081815260208120601f850160051c81016020861015620002705750805b601f850160051c820191505b8181101562000291578281556001016200027c565b5050505b505050565b81516001600160401b03811115620002b657620002b6620001f5565b620002ce81620002c784546200020b565b8462000247565b602080601f831160018114620003065760008415620002ed5750858301515b600019600386901b1c1916600185901b17855562000291565b600085815260208120601f198616915b82811015620003375788860151825594840194600190910190840162000316565b5085821015620003565787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051614b6d620003c16000396000818161098801528181610bc501528181610ec90152818161114d0152818161134e01528181611c5601528181611fc5015281816121d0015281816123030152612a6d0152614b6d6000f3fe6080604052600436106103a15760003560e01c80637533d788116101e7578063c44618341161010d578063df2a5b3b116100a0578063f23536411161006f578063f235364114610b35578063f2fde38b14610b55578063f5ecbdbc14610b75578063fa25f9b614610b9557600080fd5b8063df2a5b3b14610abf578063e1d4c87014610adf578063e985e9c514610af5578063eb8d72b714610b1557600080fd5b8063d12473a5116100dc578063d12473a514610a56578063d1deba1f14610a76578063da09f15d14610a89578063ddca3f4314610aa957600080fd5b8063c4461834146109ea578063c87b56dd14610a00578063c9fbdc3614610a20578063cbed8b9c14610a3657600080fd5b80639f38369a11610185578063af3fb21c11610154578063af3fb21c1461094e578063b353aaa714610976578063b88d4fde146109aa578063baf3292d146109ca57600080fd5b80639f38369a146108db578063a22cb465146108fb578063a6c3d1651461091b578063ab3ffb931461093b57600080fd5b80638ffa1f2a116101c15780638ffa1f2a14610866578063950c8a741461088657806395d89b41146108a65780639ea5d6b1146108bb57600080fd5b80637533d788146107f05780638cfd8f5c146108105780638da5cb5b1461084857600080fd5b80633f1f4fa4116102cc5780635b8c41e61161026a5780636a627842116102395780636a627842146107925780636aa99da3146107a557806370a08231146107bb578063715018a6146107db57600080fd5b80635b8c41e6146106e35780636352211e1461073257806366ad5c8a1461075257806369fe0e2d1461077257600080fd5b806348288190116102a6578063482881901461067a5780634ac3f4ff146106905780635154c0b4146106bd57806351905636146106d057600080fd5b80633f1f4fa4146105ff57806342842e0e1461063a57806342d65a8d1461065a57600080fd5b80630df374831161034457806323b872dd1161031357806323b872dd146105825780632a205e3d146105a25780633ccfd60b146105d75780633d8b38f6146105df57600080fd5b80630df37483146104b757806310ddb137146104d75780631249c58b146104f757806322a3ecf9146104ff57600080fd5b806307e0db171161038057806307e0db171461041f578063081812fc1461043f578063095ea7b3146104775780630b4cad4c1461049757600080fd5b80621d3567146103a657806301ffc9a7146103c857806306fdde03146103fd575b600080fd5b3480156103b257600080fd5b506103c66103c1366004613988565b610bc2565b005b3480156103d457600080fd5b506103e86103e3366004613a31565b610df3565b60405190151581526020015b60405180910390f35b34801561040957600080fd5b50610412610e16565b6040516103f49190613a9e565b34801561042b57600080fd5b506103c661043a366004613ab1565b610ea8565b34801561044b57600080fd5b5061045f61045a366004613acc565b610f31565b6040516001600160a01b0390911681526020016103f4565b34801561048357600080fd5b506103c6610492366004613b05565b610f58565b3480156104a357600080fd5b506103c66104b2366004613acc565b61106d565b3480156104c357600080fd5b506103c66104d2366004613b31565b61110d565b3480156104e357600080fd5b506103c66104f2366004613ab1565b61112c565b6103c6611184565b34801561050b57600080fd5b5061055361051a366004613acc565b600a6020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b03909316602085015291830152151560608201526080016103f4565b34801561058e57600080fd5b506103c661059d366004613b4d565b611190565b3480156105ae57600080fd5b506105c26105bd366004613c61565b6111c2565b604080519283526020830191909152016103f4565b6103c66111e8565b3480156105eb57600080fd5b506103e86105fa366004613cef565b611248565b34801561060b57600080fd5b5061062c61061a366004613ab1565b60036020526000908152604090205481565b6040519081526020016103f4565b34801561064657600080fd5b506103c6610655366004613b4d565b611314565b34801561066657600080fd5b506103c6610675366004613cef565b61132f565b34801561068657600080fd5b5061062c60075481565b34801561069c57600080fd5b5061062c6106ab366004613ab1565b60086020526000908152604090205481565b6103c66106cb366004613d41565b6113b5565b6103c66106de366004613da0565b611409565b3480156106ef57600080fd5b5061062c6106fe366004613e59565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561073e57600080fd5b5061045f61074d366004613acc565b611420565b34801561075e57600080fd5b506103c661076d366004613988565b611480565b34801561077e57600080fd5b506103c661078d366004613acc565b61155c565b6103c66107a0366004613eb6565b611569565b3480156107b157600080fd5b5061062c60135481565b3480156107c757600080fd5b5061062c6107d6366004613eb6565b611572565b3480156107e757600080fd5b506103c66115f8565b3480156107fc57600080fd5b5061041261080b366004613ab1565b61160a565b34801561081c57600080fd5b5061062c61082b366004613ed3565b600260209081526000928352604080842090915290825290205481565b34801561085457600080fd5b506000546001600160a01b031661045f565b34801561087257600080fd5b506103c6610881366004613f06565b6116a4565b34801561089257600080fd5b5060045461045f906001600160a01b031681565b3480156108b257600080fd5b506104126118ec565b3480156108c757600080fd5b506103c66108d6366004613b31565b6118fb565b3480156108e757600080fd5b506104126108f6366004613ab1565b6119b2565b34801561090757600080fd5b506103c6610916366004613f3a565b611ac8565b34801561092757600080fd5b506103c6610936366004613cef565b611ad7565b6103c6610949366004613fef565b611b60565b34801561095a57600080fd5b50610963600181565b60405161ffff90911681526020016103f4565b34801561098257600080fd5b5061045f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156109b657600080fd5b506103c66109c53660046140a4565b611b6f565b3480156109d657600080fd5b506103c66109e5366004613eb6565b611ba7565b3480156109f657600080fd5b5061062c61271081565b348015610a0c57600080fd5b50610412610a1b366004613acc565b611bfd565b348015610a2c57600080fd5b5061062c60125481565b348015610a4257600080fd5b506103c6610a5136600461410f565b611c37565b348015610a6257600080fd5b506103c6610a71366004613b31565b611ccc565b6103c6610a84366004613988565b611d7c565b348015610a9557600080fd5b506105c2610aa436600461417d565b611f92565b348015610ab557600080fd5b5061062c60115481565b348015610acb57600080fd5b506103c6610ada3660046141a9565b612057565b348015610aeb57600080fd5b5061062c60145481565b348015610b0157600080fd5b506103e8610b103660046141e5565b612109565b348015610b2157600080fd5b506103c6610b30366004613cef565b612137565b348015610b4157600080fd5b506105c2610b5036600461421e565b612191565b348015610b6157600080fd5b506103c6610b70366004613eb6565b61225c565b348015610b8157600080fd5b50610412610b90366004614297565b6122d2565b348015610ba157600080fd5b5061062c610bb0366004613ab1565b60096020526000908152604090205481565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614610c3f5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610c5d906142e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610c89906142e4565b8015610cd65780601f10610cab57610100808354040283529160200191610cd6565b820191906000526020600020905b815481529060010190602001808311610cb957829003601f168201915b50505050509050805186869050148015610cf1575060008151115b8015610d19575080516020820120604051610d0f908890889061431e565b6040518091039020145b610d745760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610c36565b610dea8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061238592505050565b50505050505050565b60006001600160e01b031982161580610e105750610e10826123fe565b92915050565b6060600b8054610e25906142e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610e51906142e4565b8015610e9e5780601f10610e7357610100808354040283529160200191610e9e565b820191906000526020600020905b815481529060010190602001808311610e8157829003601f168201915b5050505050905090565b610eb061243e565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610f1657600080fd5b505af1158015610f2a573d6000803e3d6000fd5b5050505050565b6000610f3c82612498565b506000908152600f60205260409020546001600160a01b031690565b6000610f6382611420565b9050806001600160a01b0316836001600160a01b031603610fd05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c36565b336001600160a01b0382161480610fec5750610fec8133612109565b61105e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c36565b61106883836124e8565b505050565b61107561243e565b600081116110d15760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b6064820152608401610c36565b60078190556040518181527ffebbc4f8bb9ec2313950c718d43123124b15778efda4c1f1d529de2995b4f34d906020015b60405180910390a150565b61111561243e565b61ffff909116600090815260036020526040902055565b61113461243e565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb13790602401610efc565b61118e6000612556565b565b61119b335b82612658565b6111b75760405162461bcd60e51b8152600401610c369061432e565b6110688383836126b6565b6000806111da87876111d38861281a565b8787612191565b915091509550959350505050565b6111f061243e565b604051600090339047908381818185875af1925050503d8060008114611232576040519150601f19603f3d011682016040523d82523d6000602084013e611237565b606091505b505090508061124557600080fd5b50565b61ffff831660009081526001602052604081208054829190611269906142e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611295906142e4565b80156112e25780601f106112b7576101008083540402835291602001916112e2565b820191906000526020600020905b8154815290600101906020018083116112c557829003601f168201915b5050505050905083836040516112f992919061431e565b60405180910390208180519060200120149150509392505050565b61106883838360405180602001604052806000815250611b6f565b61133761243e565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d90611387908690869086906004016143a4565b600060405180830381600087803b1580156113a157600080fd5b505af1158015610dea573d6000803e3d6000fd5b61ffff83166000908152600960205260409020546113d99084906001908490612865565b60408051336020820152600081830152815180820383018152606090910190915261106890849030858534612944565b610dea8787876114188861281a565b878787612ae9565b6000818152600d60205260408120546001600160a01b031680610e105760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c36565b3330146114de5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610c36565b6115548686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612cbd92505050565b505050505050565b61156461243e565b601155565b61124581612556565b60006001600160a01b0382166115dc5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c36565b506001600160a01b03166000908152600e602052604090205490565b61160061243e565b61118e6000612e3c565b60016020526000908152604090208054611623906142e4565b80601f016020809104026020016040519081016040528092919081815260200182805461164f906142e4565b801561169c5780601f106116715761010080835404028352916020019161169c565b820191906000526020600020905b81548152906001019060200180831161167f57829003601f168201915b505050505081565b6116ac612e8c565b80516020808301919091206000818152600a90925260409091206002015460ff1661170d5760405162461bcd60e51b81526020600482015260116024820152701b9bc818dc99591a5d1cc81cdd1bdc9959607a1b6044820152606401610c36565b6000828060200190518101906117239190614407565b6000848152600a60205260408120805460019091015492945090925061175f9161ffff8216916201000090046001600160a01b03169085612ee5565b6000848152600a602052604090206001015490915081116117d45760405162461bcd60e51b815260206004820152602960248201527f6e6f7420656e6f7567682067617320746f2070726f6365737320637265646974604482015268103a3930b739b332b960b91b6064820152608401610c36565b8151810361184b576000838152600a602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba2339061183e9085815260200190565b60405180910390a16118df565b604080516080810182526000858152600a6020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b5050506112456001600655565b6060600c8054610e25906142e4565b61190361243e565b6000811161195e5760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610c36565b61ffff8216600081815260086020908152604091829020849055815192835282018390527f7315f7654d594ead24a30160ed9ba2d23247f543016b918343591e93d7afdb6d91015b60405180910390a15050565b61ffff81166000908152600160205260408120805460609291906119d5906142e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611a01906142e4565b8015611a4e5780601f10611a2357610100808354040283529160200191611a4e565b820191906000526020600020905b815481529060010190602001808311611a3157829003601f168201915b505050505090508051600003611aa65760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610c36565b611ac1600060148351611ab991906144d7565b839190612f31565b9392505050565b611ad333838361303e565b5050565b611adf61243e565b818130604051602001611af4939291906144ea565b60408051601f1981840301815291815261ffff8516600090815260016020522090611b1f9082614556565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051611b53939291906143a4565b60405180910390a1505050565b610dea87878787878787612ae9565b611b793383612658565b611b955760405162461bcd60e51b8152600401610c369061432e565b611ba18484848461310c565b50505050565b611baf61243e565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b90602001611102565b6060611c0761313f565b611c108361315f565b604051602001611c21929190614615565b6040516020818303038152906040529050919050565b611c3f61243e565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c90611c939088908890889088908890600401614644565b600060405180830381600087803b158015611cad57600080fd5b505af1158015611cc1573d6000803e3d6000fd5b505050505050505050565b611cd461243e565b60008111611d305760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610c36565b61ffff8216600081815260096020908152604091829020849055815192835282018390527fc46df2983228ac2d9754e94a0d565e6671665dc8ad38602bc8e544f0685a29fb91016119a6565b61ffff86166000908152600560205260408082209051611d9f908890889061431e565b90815260408051602092819003830190206001600160401b03871660009081529252902054905080611e1f5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610c36565b808383604051611e3092919061431e565b604051809103902014611e8f5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610c36565b61ffff87166000908152600560205260408082209051611eb2908990899061431e565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252611f4a918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612cbd92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e58787878785604051611f8195949392919061467d565b60405180910390a150505050505050565b604080513360208201526000818301819052825180830384018152606083019384905263040a7bb160e41b9093529182917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906340a7bb109061200a908990309086908b908b906064016146b8565b6040805180830381865afa158015612026573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204a919061470c565b9250925050935093915050565b61205f61243e565b600081116120a75760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b6044820152606401610c36565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611b53565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b61213f61243e565b61ffff8316600090815260016020526040902061215d828483614730565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab838383604051611b53939291906143a4565b600080600086866040516020016121a992919061482a565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb109061220d908b90309086908b908b906004016146b8565b6040805180830381865afa158015612229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224d919061470c565b92509250509550959350505050565b61226461243e565b6001600160a01b0381166122c95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c36565b61124581612e3c565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc90608401600060405180830381865afa158015612352573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261237a9190810190614858565b90505b949350505050565b6000806123e85a60966366ad5c8a60e01b898989896040516024016123ad949392919061488c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152309291906131f1565b915091508161155457611554868686868561327b565b60006001600160e01b031982166380ac58cd60e01b148061242f57506001600160e01b03198216635b5e139f60e01b145b80610e105750610e1082613318565b6000546001600160a01b0316331461118e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c36565b6124a18161334d565b6112455760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c36565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061251d82611420565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60115434101561259d5760405162461bcd60e51b815260206004820152601260248201527124b739bab33334b1b4b2b73a1022ba3432b960711b6044820152606401610c36565b60145460135411156125e15760405162461bcd60e51b815260206004820152600d60248201526c26b4b73a34b7339022b93937b960991b6044820152606401610c36565b6013805490819060006125f3836148ca565b9190505550612602338261336a565b6001600160a01b03821615611ad357604080518281526001600160a01b038416602082015233917f0dbf48b2d95441997ef389702675fe528a55fde0899829fa0f9af2325781bc51910160405180910390a25050565b60008061266483611420565b9050806001600160a01b0316846001600160a01b0316148061268b575061268b8185612109565b8061237d5750836001600160a01b03166126a484610f31565b6001600160a01b031614949350505050565b826001600160a01b03166126c982611420565b6001600160a01b0316146126ef5760405162461bcd60e51b8152600401610c36906148e3565b6001600160a01b0382166127515760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c36565b826001600160a01b031661276482611420565b6001600160a01b03161461278a5760405162461bcd60e51b8152600401610c36906148e3565b6000818152600f6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600e8552838620805460001901905590871680865283862080546001019055868652600d90945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061285457612854614928565b602090810291909101015292915050565b600061287083613384565b61ffff8087166000908152600260209081526040808320938916835292905290812054919250906128a290849061493e565b9050600081116128f45760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610c36565b808210156115545760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610c36565b61ffff861660009081526001602052604081208054612962906142e4565b80601f016020809104026020016040519081016040528092919081815260200182805461298e906142e4565b80156129db5780601f106129b0576101008083540402835291602001916129db565b820191906000526020600020905b8154815290600101906020018083116129be57829003601f168201915b505050505090508051600003612a4c5760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610c36565b612a578787516133e0565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c5803100908490612aae908b9086908c908c908c908c90600401614951565b6000604051808303818588803b158015612ac757600080fd5b505af1158015612adb573d6000803e3d6000fd5b505050505050505050505050565b6000845111612b305760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610c36565b835160011480612b54575061ffff8616600090815260086020526040902054845111155b612bab5760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610c36565b60005b8451811015612bee57612bdc888888888581518110612bcf57612bcf614928565b6020026020010151613451565b80612be6816148ca565b915050612bae565b5060008585604051602001612c0492919061482a565b6040516020818303038152906040529050612c49876001848851600960008d61ffff1661ffff16815260200190815260200160002054612c4491906149b8565b612865565b612c57878286868634612944565b85604051612c6591906149cf565b6040518091039020886001600160a01b03168861ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a88604051612cab91906149eb565b60405180910390a45050505050505050565b60008082806020019051810190612cd49190614407565b9150915080600081518110612ceb57612ceb614928565b6020026020010151600003612d01575050611ba1565b60148201516000612d1488838386612ee5565b90508251811015612de85784516020808701919091206040805160808101825261ffff808d1682526001600160a01b038088168387019081528385018881526001606086018181526000898152600a909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612dde90839089906149fe565b60405180910390a1505b816001600160a01b031687604051612e0091906149cf565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612cab91906149eb565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600260065403612ede5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c36565b6002600655565b6000825b825181101561237a576007545a1061237a57612f1f8686858481518110612f1257612f12614928565b602002602001015161353c565b80612f29816148ca565b915050612ee9565b606081612f3f81601f61493e565b1015612f7e5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610c36565b612f88828461493e565b84511015612fcc5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610c36565b606082158015612feb5760405191506000825260208201604052613035565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561302457805183526020928301920161300c565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b03160361309f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c36565b6001600160a01b03838116600081815260106020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6131178484846126b6565b6131238484848461359c565b611ba15760405162461bcd60e51b8152600401610c3690614a17565b6060604051806060016040528060228152602001614b1660229139905090565b6060600061316c8361369a565b60010190506000816001600160401b0381111561318b5761318b613b8e565b6040519080825280601f01601f1916602001820160405280156131b5576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846131bf57509392505050565b6000606060008060008661ffff166001600160401b0381111561321657613216613b8e565b6040519080825280601f01601f191660200182016040528015613240576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613262578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff168152602001908152602001600020856040516132ac91906149cf565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c906133099087908790879087908790614a69565b60405180910390a15050505050565b60006001600160e01b031982166322bac5d960e01b1480610e1057506301ffc9a760e01b6001600160e01b0319831614610e10565b6000908152600d60205260409020546001600160a01b0316151590565b611ad3828260405180602001604052806000815250613772565b60006022825110156133d85760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610c36565b506022015190565b61ffff82166000908152600360205260408120549081900361340157506127105b808211156110685760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610c36565b61345a33611195565b6134bd5760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610c36565b836001600160a01b03166134d082611420565b6001600160a01b0316146135315760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610c36565b611ba18430836126b6565b6135458161334d565b158061357157506135558161334d565b801561357157503061356682611420565b6001600160a01b0316145b61357a57600080fd5b6135838161334d565b61359157611068828261336a565b6110683083836126b6565b60006001600160a01b0384163b1561369257604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906135e0903390899088908890600401614abb565b6020604051808303816000875af192505050801561361b575060408051601f3d908101601f1916820190925261361891810190614af8565b60015b613678573d808015613649576040519150601f19603f3d011682016040523d82523d6000602084013e61364e565b606091505b5080516000036136705760405162461bcd60e51b8152600401610c3690614a17565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061237d565b50600161237d565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106136d95772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310613705576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061372357662386f26fc10000830492506010015b6305f5e100831061373b576305f5e100830492506008015b612710831061374f57612710830492506004015b60648310613761576064830492506002015b600a8310610e105760010192915050565b61377c83836137a5565b613789600084848461359c565b6110685760405162461bcd60e51b8152600401610c3690614a17565b6001600160a01b0382166137fb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c36565b6138048161334d565b156138515760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c36565b61385a8161334d565b156138a75760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c36565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b803561ffff8116811461392457600080fd5b919050565b60008083601f84011261393b57600080fd5b5081356001600160401b0381111561395257600080fd5b60208301915083602082850101111561396a57600080fd5b9250929050565b80356001600160401b038116811461392457600080fd5b600080600080600080608087890312156139a157600080fd5b6139aa87613912565b955060208701356001600160401b03808211156139c657600080fd5b6139d28a838b01613929565b90975095508591506139e660408a01613971565b945060608901359150808211156139fc57600080fd5b50613a0989828a01613929565b979a9699509497509295939492505050565b6001600160e01b03198116811461124557600080fd5b600060208284031215613a4357600080fd5b8135611ac181613a1b565b60005b83811015613a69578181015183820152602001613a51565b50506000910152565b60008151808452613a8a816020860160208601613a4e565b601f01601f19169290920160200192915050565b602081526000611ac16020830184613a72565b600060208284031215613ac357600080fd5b611ac182613912565b600060208284031215613ade57600080fd5b5035919050565b6001600160a01b038116811461124557600080fd5b803561392481613ae5565b60008060408385031215613b1857600080fd5b8235613b2381613ae5565b946020939093013593505050565b60008060408385031215613b4457600080fd5b613b2383613912565b600080600060608486031215613b6257600080fd5b8335613b6d81613ae5565b92506020840135613b7d81613ae5565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613bcc57613bcc613b8e565b604052919050565b60006001600160401b03821115613bed57613bed613b8e565b50601f01601f191660200190565b600082601f830112613c0c57600080fd5b8135613c1f613c1a82613bd4565b613ba4565b818152846020838601011115613c3457600080fd5b816020850160208301376000918101602001919091529392505050565b8035801515811461392457600080fd5b600080600080600060a08688031215613c7957600080fd5b613c8286613912565b945060208601356001600160401b0380821115613c9e57600080fd5b613caa89838a01613bfb565b955060408801359450613cbf60608901613c51565b93506080880135915080821115613cd557600080fd5b50613ce288828901613bfb565b9150509295509295909350565b600080600060408486031215613d0457600080fd5b613d0d84613912565b925060208401356001600160401b03811115613d2857600080fd5b613d3486828701613929565b9497909650939450505050565b600080600060608486031215613d5657600080fd5b613d5f84613912565b92506020840135613d6f81613ae5565b915060408401356001600160401b03811115613d8a57600080fd5b613d9686828701613bfb565b9150509250925092565b600080600080600080600060e0888a031215613dbb57600080fd5b8735613dc681613ae5565b9650613dd460208901613912565b955060408801356001600160401b0380821115613df057600080fd5b613dfc8b838c01613bfb565b965060608a0135955060808a01359150613e1582613ae5565b90935060a089013590613e2782613ae5565b90925060c08901359080821115613e3d57600080fd5b50613e4a8a828b01613bfb565b91505092959891949750929550565b600080600060608486031215613e6e57600080fd5b613e7784613912565b925060208401356001600160401b03811115613e9257600080fd5b613e9e86828701613bfb565b925050613ead60408501613971565b90509250925092565b600060208284031215613ec857600080fd5b8135611ac181613ae5565b60008060408385031215613ee657600080fd5b613eef83613912565b9150613efd60208401613912565b90509250929050565b600060208284031215613f1857600080fd5b81356001600160401b03811115613f2e57600080fd5b61237d84828501613bfb565b60008060408385031215613f4d57600080fd5b8235613f5881613ae5565b9150613efd60208401613c51565b60006001600160401b03821115613f7f57613f7f613b8e565b5060051b60200190565b600082601f830112613f9a57600080fd5b81356020613faa613c1a83613f66565b82815260059290921b84018101918181019086841115613fc957600080fd5b8286015b84811015613fe45780358352918301918301613fcd565b509695505050505050565b600080600080600080600060e0888a03121561400a57600080fd5b873561401581613ae5565b965061402360208901613912565b955060408801356001600160401b038082111561403f57600080fd5b61404b8b838c01613bfb565b965060608a013591508082111561406157600080fd5b61406d8b838c01613f89565b955060808a0135915061407f82613ae5565b81945061408e60a08b01613afa565b935060c08a0135915080821115613e3d57600080fd5b600080600080608085870312156140ba57600080fd5b84356140c581613ae5565b935060208501356140d581613ae5565b92506040850135915060608501356001600160401b038111156140f757600080fd5b61410387828801613bfb565b91505092959194509250565b60008060008060006080868803121561412757600080fd5b61413086613912565b945061413e60208701613912565b93506040860135925060608601356001600160401b0381111561416057600080fd5b61416c88828901613929565b969995985093965092949392505050565b60008060006060848603121561419257600080fd5b61419b84613912565b9250613d6f60208501613c51565b6000806000606084860312156141be57600080fd5b6141c784613912565b92506141d560208501613912565b9150604084013590509250925092565b600080604083850312156141f857600080fd5b823561420381613ae5565b9150602083013561421381613ae5565b809150509250929050565b600080600080600060a0868803121561423657600080fd5b61423f86613912565b945060208601356001600160401b038082111561425b57600080fd5b61426789838a01613bfb565b9550604088013591508082111561427d57600080fd5b61428989838a01613f89565b9450613cbf60608901613c51565b600080600080608085870312156142ad57600080fd5b6142b685613912565b93506142c460208601613912565b925060408501356142d481613ae5565b9396929550929360600135925050565b600181811c908216806142f857607f821691505b60208210810361431857634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff8416815260406020820152600061237a60408301848661437b565b600082601f8301126143d357600080fd5b81516143e1613c1a82613bd4565b8181528460208386010111156143f657600080fd5b61237d826020830160208701613a4e565b6000806040838503121561441a57600080fd5b82516001600160401b038082111561443157600080fd5b61443d868387016143c2565b935060209150818501518181111561445457600080fd5b85019050601f8101861361446757600080fd5b8051614475613c1a82613f66565b81815260059190911b8201830190838101908883111561449457600080fd5b928401925b828410156144b257835182529284019290840190614499565b80955050505050509250929050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610e1057610e106144c1565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b601f82111561106857600081815260208120601f850160051c810160208610156145375750805b601f850160051c820191505b8181101561155457828155600101614543565b81516001600160401b0381111561456f5761456f613b8e565b6145838161457d84546142e4565b84614510565b602080601f8311600181146145b857600084156145a05750858301515b600019600386901b1c1916600185901b178555611554565b600085815260208120601f198616915b828110156145e7578886015182559484019460019091019084016145c8565b50858210156146055787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008351614627818460208801613a4e565b83519083019061463b818360208801613a4e565b01949350505050565b600061ffff80881683528087166020840152508460408301526080606083015261467260808301848661437b565b979650505050505050565b61ffff8616815260806020820152600061469b60808301868861437b565b6001600160401b0394909416604083015250606001529392505050565b61ffff861681526001600160a01b038516602082015260a0604082018190526000906146e690830186613a72565b841515606084015282810360808401526147008185613a72565b98975050505050505050565b6000806040838503121561471f57600080fd5b505080516020909101519092909150565b6001600160401b0383111561474757614747613b8e565b61475b8361475583546142e4565b83614510565b6000601f84116001811461478f57600085156147775750838201355b600019600387901b1c1916600186901b178355610f2a565b600083815260209020601f19861690835b828110156147c057868501358255602094850194600190920191016147a0565b50868210156147dd5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600081518084526020808501945080840160005b8381101561481f57815187529582019590820190600101614803565b509495945050505050565b60408152600061483d6040830185613a72565b828103602084015261484f81856147ef565b95945050505050565b60006020828403121561486a57600080fd5b81516001600160401b0381111561488057600080fd5b61237d848285016143c2565b61ffff851681526080602082015260006148a96080830186613a72565b6001600160401b038516604084015282810360608401526146728185613a72565b6000600182016148dc576148dc6144c1565b5060010190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b80820180821115610e1057610e106144c1565b61ffff8716815260c06020820152600061496e60c0830188613a72565b82810360408401526149808188613a72565b6001600160a01b0387811660608601528616608085015283810360a085015290506149ab8185613a72565b9998505050505050505050565b8082028115828204841417610e1057610e106144c1565b600082516149e1818460208701613a4e565b9190910192915050565b602081526000611ac160208301846147ef565b82815260406020820152600061237d6040830184613a72565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b61ffff8616815260a060208201526000614a8660a0830187613a72565b6001600160401b03861660408401528281036060840152614aa78186613a72565b905082810360808401526147008185613a72565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614aee90830184613a72565b9695505050505050565b600060208284031215614b0a57600080fd5b8151611ac181613a1b56fe68747470733a2f2f6170692e6f6d6e697472756d2e636f6d2f6170692f6f6d6e692fa26469706673582212200596b71c81cbed2675e7f1a3817ac347dca4a3f53049c443329729b4e3c197f564736f6c634300081300330000000000000000000000000000000000000000000000000000000000030d40000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7000000000000000000000000000000000000000000000000000000000f7f4900000000000000000000000000000000000000000000000000000000001017df7f
Deployed Bytecode
0x6080604052600436106103a15760003560e01c80637533d788116101e7578063c44618341161010d578063df2a5b3b116100a0578063f23536411161006f578063f235364114610b35578063f2fde38b14610b55578063f5ecbdbc14610b75578063fa25f9b614610b9557600080fd5b8063df2a5b3b14610abf578063e1d4c87014610adf578063e985e9c514610af5578063eb8d72b714610b1557600080fd5b8063d12473a5116100dc578063d12473a514610a56578063d1deba1f14610a76578063da09f15d14610a89578063ddca3f4314610aa957600080fd5b8063c4461834146109ea578063c87b56dd14610a00578063c9fbdc3614610a20578063cbed8b9c14610a3657600080fd5b80639f38369a11610185578063af3fb21c11610154578063af3fb21c1461094e578063b353aaa714610976578063b88d4fde146109aa578063baf3292d146109ca57600080fd5b80639f38369a146108db578063a22cb465146108fb578063a6c3d1651461091b578063ab3ffb931461093b57600080fd5b80638ffa1f2a116101c15780638ffa1f2a14610866578063950c8a741461088657806395d89b41146108a65780639ea5d6b1146108bb57600080fd5b80637533d788146107f05780638cfd8f5c146108105780638da5cb5b1461084857600080fd5b80633f1f4fa4116102cc5780635b8c41e61161026a5780636a627842116102395780636a627842146107925780636aa99da3146107a557806370a08231146107bb578063715018a6146107db57600080fd5b80635b8c41e6146106e35780636352211e1461073257806366ad5c8a1461075257806369fe0e2d1461077257600080fd5b806348288190116102a6578063482881901461067a5780634ac3f4ff146106905780635154c0b4146106bd57806351905636146106d057600080fd5b80633f1f4fa4146105ff57806342842e0e1461063a57806342d65a8d1461065a57600080fd5b80630df374831161034457806323b872dd1161031357806323b872dd146105825780632a205e3d146105a25780633ccfd60b146105d75780633d8b38f6146105df57600080fd5b80630df37483146104b757806310ddb137146104d75780631249c58b146104f757806322a3ecf9146104ff57600080fd5b806307e0db171161038057806307e0db171461041f578063081812fc1461043f578063095ea7b3146104775780630b4cad4c1461049757600080fd5b80621d3567146103a657806301ffc9a7146103c857806306fdde03146103fd575b600080fd5b3480156103b257600080fd5b506103c66103c1366004613988565b610bc2565b005b3480156103d457600080fd5b506103e86103e3366004613a31565b610df3565b60405190151581526020015b60405180910390f35b34801561040957600080fd5b50610412610e16565b6040516103f49190613a9e565b34801561042b57600080fd5b506103c661043a366004613ab1565b610ea8565b34801561044b57600080fd5b5061045f61045a366004613acc565b610f31565b6040516001600160a01b0390911681526020016103f4565b34801561048357600080fd5b506103c6610492366004613b05565b610f58565b3480156104a357600080fd5b506103c66104b2366004613acc565b61106d565b3480156104c357600080fd5b506103c66104d2366004613b31565b61110d565b3480156104e357600080fd5b506103c66104f2366004613ab1565b61112c565b6103c6611184565b34801561050b57600080fd5b5061055361051a366004613acc565b600a6020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b03909316602085015291830152151560608201526080016103f4565b34801561058e57600080fd5b506103c661059d366004613b4d565b611190565b3480156105ae57600080fd5b506105c26105bd366004613c61565b6111c2565b604080519283526020830191909152016103f4565b6103c66111e8565b3480156105eb57600080fd5b506103e86105fa366004613cef565b611248565b34801561060b57600080fd5b5061062c61061a366004613ab1565b60036020526000908152604090205481565b6040519081526020016103f4565b34801561064657600080fd5b506103c6610655366004613b4d565b611314565b34801561066657600080fd5b506103c6610675366004613cef565b61132f565b34801561068657600080fd5b5061062c60075481565b34801561069c57600080fd5b5061062c6106ab366004613ab1565b60086020526000908152604090205481565b6103c66106cb366004613d41565b6113b5565b6103c66106de366004613da0565b611409565b3480156106ef57600080fd5b5061062c6106fe366004613e59565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561073e57600080fd5b5061045f61074d366004613acc565b611420565b34801561075e57600080fd5b506103c661076d366004613988565b611480565b34801561077e57600080fd5b506103c661078d366004613acc565b61155c565b6103c66107a0366004613eb6565b611569565b3480156107b157600080fd5b5061062c60135481565b3480156107c757600080fd5b5061062c6107d6366004613eb6565b611572565b3480156107e757600080fd5b506103c66115f8565b3480156107fc57600080fd5b5061041261080b366004613ab1565b61160a565b34801561081c57600080fd5b5061062c61082b366004613ed3565b600260209081526000928352604080842090915290825290205481565b34801561085457600080fd5b506000546001600160a01b031661045f565b34801561087257600080fd5b506103c6610881366004613f06565b6116a4565b34801561089257600080fd5b5060045461045f906001600160a01b031681565b3480156108b257600080fd5b506104126118ec565b3480156108c757600080fd5b506103c66108d6366004613b31565b6118fb565b3480156108e757600080fd5b506104126108f6366004613ab1565b6119b2565b34801561090757600080fd5b506103c6610916366004613f3a565b611ac8565b34801561092757600080fd5b506103c6610936366004613cef565b611ad7565b6103c6610949366004613fef565b611b60565b34801561095a57600080fd5b50610963600181565b60405161ffff90911681526020016103f4565b34801561098257600080fd5b5061045f7f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd781565b3480156109b657600080fd5b506103c66109c53660046140a4565b611b6f565b3480156109d657600080fd5b506103c66109e5366004613eb6565b611ba7565b3480156109f657600080fd5b5061062c61271081565b348015610a0c57600080fd5b50610412610a1b366004613acc565b611bfd565b348015610a2c57600080fd5b5061062c60125481565b348015610a4257600080fd5b506103c6610a5136600461410f565b611c37565b348015610a6257600080fd5b506103c6610a71366004613b31565b611ccc565b6103c6610a84366004613988565b611d7c565b348015610a9557600080fd5b506105c2610aa436600461417d565b611f92565b348015610ab557600080fd5b5061062c60115481565b348015610acb57600080fd5b506103c6610ada3660046141a9565b612057565b348015610aeb57600080fd5b5061062c60145481565b348015610b0157600080fd5b506103e8610b103660046141e5565b612109565b348015610b2157600080fd5b506103c6610b30366004613cef565b612137565b348015610b4157600080fd5b506105c2610b5036600461421e565b612191565b348015610b6157600080fd5b506103c6610b70366004613eb6565b61225c565b348015610b8157600080fd5b50610412610b90366004614297565b6122d2565b348015610ba157600080fd5b5061062c610bb0366004613ab1565b60096020526000908152604090205481565b337f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b031614610c3f5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610c5d906142e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610c89906142e4565b8015610cd65780601f10610cab57610100808354040283529160200191610cd6565b820191906000526020600020905b815481529060010190602001808311610cb957829003601f168201915b50505050509050805186869050148015610cf1575060008151115b8015610d19575080516020820120604051610d0f908890889061431e565b6040518091039020145b610d745760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610c36565b610dea8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061238592505050565b50505050505050565b60006001600160e01b031982161580610e105750610e10826123fe565b92915050565b6060600b8054610e25906142e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610e51906142e4565b8015610e9e5780601f10610e7357610100808354040283529160200191610e9e565b820191906000526020600020905b815481529060010190602001808311610e8157829003601f168201915b5050505050905090565b610eb061243e565b6040516307e0db1760e01b815261ffff821660048201527f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610f1657600080fd5b505af1158015610f2a573d6000803e3d6000fd5b5050505050565b6000610f3c82612498565b506000908152600f60205260409020546001600160a01b031690565b6000610f6382611420565b9050806001600160a01b0316836001600160a01b031603610fd05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c36565b336001600160a01b0382161480610fec5750610fec8133612109565b61105e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c36565b61106883836124e8565b505050565b61107561243e565b600081116110d15760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b6064820152608401610c36565b60078190556040518181527ffebbc4f8bb9ec2313950c718d43123124b15778efda4c1f1d529de2995b4f34d906020015b60405180910390a150565b61111561243e565b61ffff909116600090815260036020526040902055565b61113461243e565b6040516310ddb13760e01b815261ffff821660048201527f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b0316906310ddb13790602401610efc565b61118e6000612556565b565b61119b335b82612658565b6111b75760405162461bcd60e51b8152600401610c369061432e565b6110688383836126b6565b6000806111da87876111d38861281a565b8787612191565b915091509550959350505050565b6111f061243e565b604051600090339047908381818185875af1925050503d8060008114611232576040519150601f19603f3d011682016040523d82523d6000602084013e611237565b606091505b505090508061124557600080fd5b50565b61ffff831660009081526001602052604081208054829190611269906142e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611295906142e4565b80156112e25780601f106112b7576101008083540402835291602001916112e2565b820191906000526020600020905b8154815290600101906020018083116112c557829003601f168201915b5050505050905083836040516112f992919061431e565b60405180910390208180519060200120149150509392505050565b61106883838360405180602001604052806000815250611b6f565b61133761243e565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd716906342d65a8d90611387908690869086906004016143a4565b600060405180830381600087803b1580156113a157600080fd5b505af1158015610dea573d6000803e3d6000fd5b61ffff83166000908152600960205260409020546113d99084906001908490612865565b60408051336020820152600081830152815180820383018152606090910190915261106890849030858534612944565b610dea8787876114188861281a565b878787612ae9565b6000818152600d60205260408120546001600160a01b031680610e105760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c36565b3330146114de5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610c36565b6115548686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612cbd92505050565b505050505050565b61156461243e565b601155565b61124581612556565b60006001600160a01b0382166115dc5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c36565b506001600160a01b03166000908152600e602052604090205490565b61160061243e565b61118e6000612e3c565b60016020526000908152604090208054611623906142e4565b80601f016020809104026020016040519081016040528092919081815260200182805461164f906142e4565b801561169c5780601f106116715761010080835404028352916020019161169c565b820191906000526020600020905b81548152906001019060200180831161167f57829003601f168201915b505050505081565b6116ac612e8c565b80516020808301919091206000818152600a90925260409091206002015460ff1661170d5760405162461bcd60e51b81526020600482015260116024820152701b9bc818dc99591a5d1cc81cdd1bdc9959607a1b6044820152606401610c36565b6000828060200190518101906117239190614407565b6000848152600a60205260408120805460019091015492945090925061175f9161ffff8216916201000090046001600160a01b03169085612ee5565b6000848152600a602052604090206001015490915081116117d45760405162461bcd60e51b815260206004820152602960248201527f6e6f7420656e6f7567682067617320746f2070726f6365737320637265646974604482015268103a3930b739b332b960b91b6064820152608401610c36565b8151810361184b576000838152600a602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba2339061183e9085815260200190565b60405180910390a16118df565b604080516080810182526000858152600a6020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b5050506112456001600655565b6060600c8054610e25906142e4565b61190361243e565b6000811161195e5760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610c36565b61ffff8216600081815260086020908152604091829020849055815192835282018390527f7315f7654d594ead24a30160ed9ba2d23247f543016b918343591e93d7afdb6d91015b60405180910390a15050565b61ffff81166000908152600160205260408120805460609291906119d5906142e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611a01906142e4565b8015611a4e5780601f10611a2357610100808354040283529160200191611a4e565b820191906000526020600020905b815481529060010190602001808311611a3157829003601f168201915b505050505090508051600003611aa65760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610c36565b611ac1600060148351611ab991906144d7565b839190612f31565b9392505050565b611ad333838361303e565b5050565b611adf61243e565b818130604051602001611af4939291906144ea565b60408051601f1981840301815291815261ffff8516600090815260016020522090611b1f9082614556565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051611b53939291906143a4565b60405180910390a1505050565b610dea87878787878787612ae9565b611b793383612658565b611b955760405162461bcd60e51b8152600401610c369061432e565b611ba18484848461310c565b50505050565b611baf61243e565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b90602001611102565b6060611c0761313f565b611c108361315f565b604051602001611c21929190614615565b6040516020818303038152906040529050919050565b611c3f61243e565b6040516332fb62e760e21b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7169063cbed8b9c90611c939088908890889088908890600401614644565b600060405180830381600087803b158015611cad57600080fd5b505af1158015611cc1573d6000803e3d6000fd5b505050505050505050565b611cd461243e565b60008111611d305760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610c36565b61ffff8216600081815260096020908152604091829020849055815192835282018390527fc46df2983228ac2d9754e94a0d565e6671665dc8ad38602bc8e544f0685a29fb91016119a6565b61ffff86166000908152600560205260408082209051611d9f908890889061431e565b90815260408051602092819003830190206001600160401b03871660009081529252902054905080611e1f5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610c36565b808383604051611e3092919061431e565b604051809103902014611e8f5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610c36565b61ffff87166000908152600560205260408082209051611eb2908990899061431e565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252611f4a918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612cbd92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e58787878785604051611f8195949392919061467d565b60405180910390a150505050505050565b604080513360208201526000818301819052825180830384018152606083019384905263040a7bb160e41b9093529182917f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b0316906340a7bb109061200a908990309086908b908b906064016146b8565b6040805180830381865afa158015612026573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204a919061470c565b9250925050935093915050565b61205f61243e565b600081116120a75760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b6044820152606401610c36565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611b53565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b61213f61243e565b61ffff8316600090815260016020526040902061215d828483614730565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab838383604051611b53939291906143a4565b600080600086866040516020016121a992919061482a565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd716906340a7bb109061220d908b90309086908b908b906004016146b8565b6040805180830381865afa158015612229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224d919061470c565b92509250509550959350505050565b61226461243e565b6001600160a01b0381166122c95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c36565b61124581612e3c565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b03169063f5ecbdbc90608401600060405180830381865afa158015612352573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261237a9190810190614858565b90505b949350505050565b6000806123e85a60966366ad5c8a60e01b898989896040516024016123ad949392919061488c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152309291906131f1565b915091508161155457611554868686868561327b565b60006001600160e01b031982166380ac58cd60e01b148061242f57506001600160e01b03198216635b5e139f60e01b145b80610e105750610e1082613318565b6000546001600160a01b0316331461118e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c36565b6124a18161334d565b6112455760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c36565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061251d82611420565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60115434101561259d5760405162461bcd60e51b815260206004820152601260248201527124b739bab33334b1b4b2b73a1022ba3432b960711b6044820152606401610c36565b60145460135411156125e15760405162461bcd60e51b815260206004820152600d60248201526c26b4b73a34b7339022b93937b960991b6044820152606401610c36565b6013805490819060006125f3836148ca565b9190505550612602338261336a565b6001600160a01b03821615611ad357604080518281526001600160a01b038416602082015233917f0dbf48b2d95441997ef389702675fe528a55fde0899829fa0f9af2325781bc51910160405180910390a25050565b60008061266483611420565b9050806001600160a01b0316846001600160a01b0316148061268b575061268b8185612109565b8061237d5750836001600160a01b03166126a484610f31565b6001600160a01b031614949350505050565b826001600160a01b03166126c982611420565b6001600160a01b0316146126ef5760405162461bcd60e51b8152600401610c36906148e3565b6001600160a01b0382166127515760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c36565b826001600160a01b031661276482611420565b6001600160a01b03161461278a5760405162461bcd60e51b8152600401610c36906148e3565b6000818152600f6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600e8552838620805460001901905590871680865283862080546001019055868652600d90945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061285457612854614928565b602090810291909101015292915050565b600061287083613384565b61ffff8087166000908152600260209081526040808320938916835292905290812054919250906128a290849061493e565b9050600081116128f45760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610c36565b808210156115545760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610c36565b61ffff861660009081526001602052604081208054612962906142e4565b80601f016020809104026020016040519081016040528092919081815260200182805461298e906142e4565b80156129db5780601f106129b0576101008083540402835291602001916129db565b820191906000526020600020905b8154815290600101906020018083116129be57829003601f168201915b505050505090508051600003612a4c5760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610c36565b612a578787516133e0565b60405162c5803160e81b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7169063c5803100908490612aae908b9086908c908c908c908c90600401614951565b6000604051808303818588803b158015612ac757600080fd5b505af1158015612adb573d6000803e3d6000fd5b505050505050505050505050565b6000845111612b305760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610c36565b835160011480612b54575061ffff8616600090815260086020526040902054845111155b612bab5760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610c36565b60005b8451811015612bee57612bdc888888888581518110612bcf57612bcf614928565b6020026020010151613451565b80612be6816148ca565b915050612bae565b5060008585604051602001612c0492919061482a565b6040516020818303038152906040529050612c49876001848851600960008d61ffff1661ffff16815260200190815260200160002054612c4491906149b8565b612865565b612c57878286868634612944565b85604051612c6591906149cf565b6040518091039020886001600160a01b03168861ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a88604051612cab91906149eb565b60405180910390a45050505050505050565b60008082806020019051810190612cd49190614407565b9150915080600081518110612ceb57612ceb614928565b6020026020010151600003612d01575050611ba1565b60148201516000612d1488838386612ee5565b90508251811015612de85784516020808701919091206040805160808101825261ffff808d1682526001600160a01b038088168387019081528385018881526001606086018181526000898152600a909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612dde90839089906149fe565b60405180910390a1505b816001600160a01b031687604051612e0091906149cf565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612cab91906149eb565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600260065403612ede5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c36565b6002600655565b6000825b825181101561237a576007545a1061237a57612f1f8686858481518110612f1257612f12614928565b602002602001015161353c565b80612f29816148ca565b915050612ee9565b606081612f3f81601f61493e565b1015612f7e5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610c36565b612f88828461493e565b84511015612fcc5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610c36565b606082158015612feb5760405191506000825260208201604052613035565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561302457805183526020928301920161300c565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b03160361309f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c36565b6001600160a01b03838116600081815260106020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6131178484846126b6565b6131238484848461359c565b611ba15760405162461bcd60e51b8152600401610c3690614a17565b6060604051806060016040528060228152602001614b1660229139905090565b6060600061316c8361369a565b60010190506000816001600160401b0381111561318b5761318b613b8e565b6040519080825280601f01601f1916602001820160405280156131b5576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846131bf57509392505050565b6000606060008060008661ffff166001600160401b0381111561321657613216613b8e565b6040519080825280601f01601f191660200182016040528015613240576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613262578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff168152602001908152602001600020856040516132ac91906149cf565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c906133099087908790879087908790614a69565b60405180910390a15050505050565b60006001600160e01b031982166322bac5d960e01b1480610e1057506301ffc9a760e01b6001600160e01b0319831614610e10565b6000908152600d60205260409020546001600160a01b0316151590565b611ad3828260405180602001604052806000815250613772565b60006022825110156133d85760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610c36565b506022015190565b61ffff82166000908152600360205260408120549081900361340157506127105b808211156110685760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610c36565b61345a33611195565b6134bd5760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610c36565b836001600160a01b03166134d082611420565b6001600160a01b0316146135315760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610c36565b611ba18430836126b6565b6135458161334d565b158061357157506135558161334d565b801561357157503061356682611420565b6001600160a01b0316145b61357a57600080fd5b6135838161334d565b61359157611068828261336a565b6110683083836126b6565b60006001600160a01b0384163b1561369257604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906135e0903390899088908890600401614abb565b6020604051808303816000875af192505050801561361b575060408051601f3d908101601f1916820190925261361891810190614af8565b60015b613678573d808015613649576040519150601f19603f3d011682016040523d82523d6000602084013e61364e565b606091505b5080516000036136705760405162461bcd60e51b8152600401610c3690614a17565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061237d565b50600161237d565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106136d95772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310613705576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061372357662386f26fc10000830492506010015b6305f5e100831061373b576305f5e100830492506008015b612710831061374f57612710830492506004015b60648310613761576064830492506002015b600a8310610e105760010192915050565b61377c83836137a5565b613789600084848461359c565b6110685760405162461bcd60e51b8152600401610c3690614a17565b6001600160a01b0382166137fb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c36565b6138048161334d565b156138515760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c36565b61385a8161334d565b156138a75760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c36565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b803561ffff8116811461392457600080fd5b919050565b60008083601f84011261393b57600080fd5b5081356001600160401b0381111561395257600080fd5b60208301915083602082850101111561396a57600080fd5b9250929050565b80356001600160401b038116811461392457600080fd5b600080600080600080608087890312156139a157600080fd5b6139aa87613912565b955060208701356001600160401b03808211156139c657600080fd5b6139d28a838b01613929565b90975095508591506139e660408a01613971565b945060608901359150808211156139fc57600080fd5b50613a0989828a01613929565b979a9699509497509295939492505050565b6001600160e01b03198116811461124557600080fd5b600060208284031215613a4357600080fd5b8135611ac181613a1b565b60005b83811015613a69578181015183820152602001613a51565b50506000910152565b60008151808452613a8a816020860160208601613a4e565b601f01601f19169290920160200192915050565b602081526000611ac16020830184613a72565b600060208284031215613ac357600080fd5b611ac182613912565b600060208284031215613ade57600080fd5b5035919050565b6001600160a01b038116811461124557600080fd5b803561392481613ae5565b60008060408385031215613b1857600080fd5b8235613b2381613ae5565b946020939093013593505050565b60008060408385031215613b4457600080fd5b613b2383613912565b600080600060608486031215613b6257600080fd5b8335613b6d81613ae5565b92506020840135613b7d81613ae5565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613bcc57613bcc613b8e565b604052919050565b60006001600160401b03821115613bed57613bed613b8e565b50601f01601f191660200190565b600082601f830112613c0c57600080fd5b8135613c1f613c1a82613bd4565b613ba4565b818152846020838601011115613c3457600080fd5b816020850160208301376000918101602001919091529392505050565b8035801515811461392457600080fd5b600080600080600060a08688031215613c7957600080fd5b613c8286613912565b945060208601356001600160401b0380821115613c9e57600080fd5b613caa89838a01613bfb565b955060408801359450613cbf60608901613c51565b93506080880135915080821115613cd557600080fd5b50613ce288828901613bfb565b9150509295509295909350565b600080600060408486031215613d0457600080fd5b613d0d84613912565b925060208401356001600160401b03811115613d2857600080fd5b613d3486828701613929565b9497909650939450505050565b600080600060608486031215613d5657600080fd5b613d5f84613912565b92506020840135613d6f81613ae5565b915060408401356001600160401b03811115613d8a57600080fd5b613d9686828701613bfb565b9150509250925092565b600080600080600080600060e0888a031215613dbb57600080fd5b8735613dc681613ae5565b9650613dd460208901613912565b955060408801356001600160401b0380821115613df057600080fd5b613dfc8b838c01613bfb565b965060608a0135955060808a01359150613e1582613ae5565b90935060a089013590613e2782613ae5565b90925060c08901359080821115613e3d57600080fd5b50613e4a8a828b01613bfb565b91505092959891949750929550565b600080600060608486031215613e6e57600080fd5b613e7784613912565b925060208401356001600160401b03811115613e9257600080fd5b613e9e86828701613bfb565b925050613ead60408501613971565b90509250925092565b600060208284031215613ec857600080fd5b8135611ac181613ae5565b60008060408385031215613ee657600080fd5b613eef83613912565b9150613efd60208401613912565b90509250929050565b600060208284031215613f1857600080fd5b81356001600160401b03811115613f2e57600080fd5b61237d84828501613bfb565b60008060408385031215613f4d57600080fd5b8235613f5881613ae5565b9150613efd60208401613c51565b60006001600160401b03821115613f7f57613f7f613b8e565b5060051b60200190565b600082601f830112613f9a57600080fd5b81356020613faa613c1a83613f66565b82815260059290921b84018101918181019086841115613fc957600080fd5b8286015b84811015613fe45780358352918301918301613fcd565b509695505050505050565b600080600080600080600060e0888a03121561400a57600080fd5b873561401581613ae5565b965061402360208901613912565b955060408801356001600160401b038082111561403f57600080fd5b61404b8b838c01613bfb565b965060608a013591508082111561406157600080fd5b61406d8b838c01613f89565b955060808a0135915061407f82613ae5565b81945061408e60a08b01613afa565b935060c08a0135915080821115613e3d57600080fd5b600080600080608085870312156140ba57600080fd5b84356140c581613ae5565b935060208501356140d581613ae5565b92506040850135915060608501356001600160401b038111156140f757600080fd5b61410387828801613bfb565b91505092959194509250565b60008060008060006080868803121561412757600080fd5b61413086613912565b945061413e60208701613912565b93506040860135925060608601356001600160401b0381111561416057600080fd5b61416c88828901613929565b969995985093965092949392505050565b60008060006060848603121561419257600080fd5b61419b84613912565b9250613d6f60208501613c51565b6000806000606084860312156141be57600080fd5b6141c784613912565b92506141d560208501613912565b9150604084013590509250925092565b600080604083850312156141f857600080fd5b823561420381613ae5565b9150602083013561421381613ae5565b809150509250929050565b600080600080600060a0868803121561423657600080fd5b61423f86613912565b945060208601356001600160401b038082111561425b57600080fd5b61426789838a01613bfb565b9550604088013591508082111561427d57600080fd5b61428989838a01613f89565b9450613cbf60608901613c51565b600080600080608085870312156142ad57600080fd5b6142b685613912565b93506142c460208601613912565b925060408501356142d481613ae5565b9396929550929360600135925050565b600181811c908216806142f857607f821691505b60208210810361431857634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff8416815260406020820152600061237a60408301848661437b565b600082601f8301126143d357600080fd5b81516143e1613c1a82613bd4565b8181528460208386010111156143f657600080fd5b61237d826020830160208701613a4e565b6000806040838503121561441a57600080fd5b82516001600160401b038082111561443157600080fd5b61443d868387016143c2565b935060209150818501518181111561445457600080fd5b85019050601f8101861361446757600080fd5b8051614475613c1a82613f66565b81815260059190911b8201830190838101908883111561449457600080fd5b928401925b828410156144b257835182529284019290840190614499565b80955050505050509250929050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610e1057610e106144c1565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b601f82111561106857600081815260208120601f850160051c810160208610156145375750805b601f850160051c820191505b8181101561155457828155600101614543565b81516001600160401b0381111561456f5761456f613b8e565b6145838161457d84546142e4565b84614510565b602080601f8311600181146145b857600084156145a05750858301515b600019600386901b1c1916600185901b178555611554565b600085815260208120601f198616915b828110156145e7578886015182559484019460019091019084016145c8565b50858210156146055787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008351614627818460208801613a4e565b83519083019061463b818360208801613a4e565b01949350505050565b600061ffff80881683528087166020840152508460408301526080606083015261467260808301848661437b565b979650505050505050565b61ffff8616815260806020820152600061469b60808301868861437b565b6001600160401b0394909416604083015250606001529392505050565b61ffff861681526001600160a01b038516602082015260a0604082018190526000906146e690830186613a72565b841515606084015282810360808401526147008185613a72565b98975050505050505050565b6000806040838503121561471f57600080fd5b505080516020909101519092909150565b6001600160401b0383111561474757614747613b8e565b61475b8361475583546142e4565b83614510565b6000601f84116001811461478f57600085156147775750838201355b600019600387901b1c1916600186901b178355610f2a565b600083815260209020601f19861690835b828110156147c057868501358255602094850194600190920191016147a0565b50868210156147dd5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600081518084526020808501945080840160005b8381101561481f57815187529582019590820190600101614803565b509495945050505050565b60408152600061483d6040830185613a72565b828103602084015261484f81856147ef565b95945050505050565b60006020828403121561486a57600080fd5b81516001600160401b0381111561488057600080fd5b61237d848285016143c2565b61ffff851681526080602082015260006148a96080830186613a72565b6001600160401b038516604084015282810360608401526146728185613a72565b6000600182016148dc576148dc6144c1565b5060010190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b80820180821115610e1057610e106144c1565b61ffff8716815260c06020820152600061496e60c0830188613a72565b82810360408401526149808188613a72565b6001600160a01b0387811660608601528616608085015283810360a085015290506149ab8185613a72565b9998505050505050505050565b8082028115828204841417610e1057610e106144c1565b600082516149e1818460208701613a4e565b9190910192915050565b602081526000611ac160208301846147ef565b82815260406020820152600061237d6040830184613a72565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b61ffff8616815260a060208201526000614a8660a0830187613a72565b6001600160401b03861660408401528281036060840152614aa78186613a72565b905082810360808401526147008185613a72565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614aee90830184613a72565b9695505050505050565b600060208284031215614b0a57600080fd5b8151611ac181613a1b56fe68747470733a2f2f6170692e6f6d6e697472756d2e636f6d2f6170692f6f6d6e692fa26469706673582212200596b71c81cbed2675e7f1a3817ac347dca4a3f53049c443329729b4e3c197f564736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000030d40000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7000000000000000000000000000000000000000000000000000000000f7f4900000000000000000000000000000000000000000000000000000000001017df7f
-----Decoded View---------------
Arg [0] : _minGasToTransfer (uint256): 200000
Arg [1] : _layerZeroEndpoint (address): 0xb6319cC6c8c27A8F5dAF0dD3DF91EA35C4720dd7
Arg [2] : _startMintId (uint256): 260000000
Arg [3] : _endMintId (uint256): 269999999
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000030d40
Arg [1] : 000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7
Arg [2] : 000000000000000000000000000000000000000000000000000000000f7f4900
Arg [3] : 000000000000000000000000000000000000000000000000000000001017df7f
Deployed Bytecode Sourcemap
114300:2513:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41184:762;;;;;;;;;;-1:-1:-1;41184:762:0;;;;;:::i;:::-;;:::i;:::-;;113289:228;;;;;;;;;;-1:-1:-1;113289:228:0;;;;;:::i;:::-;;:::i;:::-;;;2124:14:1;;2117:22;2099:41;;2087:2;2072:18;113289:228:0;;;;;;;;98126:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;44482:123::-;;;;;;;;;;-1:-1:-1;44482:123:0;;;;;:::i;:::-;;:::i;99638:171::-;;;;;;;;;;-1:-1:-1;99638:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3445:32:1;;;3427:51;;3415:2;3400:18;99638:171:0;3281:203:1;99156:416:0;;;;;;;;;;-1:-1:-1;99156:416:0;;;;;:::i;:::-;;:::i;66012:321::-;;;;;;;;;;-1:-1:-1;66012:321:0;;;;;:::i;:::-;;:::i;46407:142::-;;;;;;;;;;-1:-1:-1;46407:142:0;;;;;:::i;:::-;;:::i;44613:129::-;;;;;;;;;;-1:-1:-1;44613:129:0;;;;;:::i;:::-;;:::i;115310:81::-;;;:::i;60125:53::-;;;;;;;;;;-1:-1:-1;60125:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60125:53:0;;;;;;;;;;;4779:6:1;4767:19;;;4749:38;;-1:-1:-1;;;;;4823:32:1;;;4818:2;4803:18;;4796:60;4872:18;;;4865:34;4942:14;4935:22;4930:2;4915:18;;4908:50;4736:3;4721:19;60125:53:0;4526:438:1;100338:301:0;;;;;;;;;;-1:-1:-1;100338:301:0;;;;;:::i;:::-;;:::i;60680:320::-;;;;;;;;;;-1:-1:-1;60680:320:0;;;;;:::i;:::-;;:::i;:::-;;;;7593:25:1;;;7649:2;7634:18;;7627:34;;;;7566:18;60680:320:0;7419:248:1;116533:192:0;;;:::i;46647:250::-;;;;;;;;;;-1:-1:-1;46647:250:0;;;;;:::i;:::-;;:::i;40726:53::-;;;;;;;;;;-1:-1:-1;40726:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;8304:25:1;;;8292:2;8277:18;40726:53:0;8158:177:1;100710:151:0;;;;;;;;;;-1:-1:-1;100710:151:0;;;;;:::i;:::-;;:::i;44750:178::-;;;;;;;;;;-1:-1:-1;44750:178:0;;;;;:::i;:::-;;:::i;59815:39::-;;;;;;;;;;;;;;;;59931:56;;;;;;;;;;-1:-1:-1;59931:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;115855:359;;;;;;:::i;:::-;;:::i;61404:351::-;;;;;;:::i;:::-;;:::i;52877:85::-;;;;;;;;;;-1:-1:-1;52877:85:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97836:223;;;;;;;;;;-1:-1:-1;97836:223:0;;;;;:::i;:::-;;:::i;54099:346::-;;;;;;;;;;-1:-1:-1;54099:346:0;;;;;:::i;:::-;;:::i;116733:75::-;;;;;;;;;;-1:-1:-1;116733:75:0;;;;;:::i;:::-;;:::i;115399:109::-;;;;;;:::i;:::-;;:::i;114418:22::-;;;;;;;;;;;;;;;;97567:207;;;;;;;;;;-1:-1:-1;97567:207:0;;;;;:::i;:::-;;:::i;12936:103::-;;;;;;;;;;;;;:::i;40596:51::-;;;;;;;;;;-1:-1:-1;40596:51:0;;;;;:::i;:::-;;:::i;40654:65::-;;;;;;;;;;-1:-1:-1;40654:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;12295:87;;;;;;;;;;-1:-1:-1;12341:7:0;12368:6;-1:-1:-1;;;;;12368:6:0;12295:87;;64222:1009;;;;;;;;;;-1:-1:-1;64222:1009:0;;;;;:::i;:::-;;:::i;40786:23::-;;;;;;;;;;-1:-1:-1;40786:23:0;;;;-1:-1:-1;;;;;40786:23:0;;;98295:104;;;;;;;;;;;;;:::i;66857:351::-;;;;;;;;;;-1:-1:-1;66857:351:0;;;;;:::i;:::-;;:::i;45579:330::-;;;;;;;;;;-1:-1:-1;45579:330:0;;;;;:::i;:::-;;:::i;99881:155::-;;;;;;;;;;-1:-1:-1;99881:155:0;;;;;:::i;:::-;;:::i;45290:281::-;;;;;;;;;;-1:-1:-1;45290:281:0;;;;;:::i;:::-;;:::i;61763:348::-;;;;;;:::i;:::-;;:::i;59578:45::-;;;;;;;;;;;;59622:1;59578:45;;;;;14250:6:1;14238:19;;;14220:38;;14208:2;14193:18;59578:45:0;14076:188:1;40543:46:0;;;;;;;;;;;;;;;100932:279;;;;;;;;;;-1:-1:-1;100932:279:0;;;;;:::i;:::-;;:::i;45917:136::-;;;;;;;;;;-1:-1:-1;45917:136:0;;;;;:::i;:::-;;:::i;40479:55::-;;;;;;;;;;;;40529:5;40479:55;;116222:166;;;;;;;;;;-1:-1:-1;116222:166:0;;;;;:::i;:::-;;:::i;114372:39::-;;;;;;;;;;;;;;;;44270:204;;;;;;;;;;-1:-1:-1;44270:204:0;;;;;:::i;:::-;;:::i;66434:359::-;;;;;;;;;;-1:-1:-1;66434:359:0;;;;;:::i;:::-;;:::i;54631:767::-;;;;;;:::i;:::-;;:::i;115518:329::-;;;;;;;;;;-1:-1:-1;115518:329:0;;;;;:::i;:::-;;:::i;114334:31::-;;;;;;;;;;;;;;;;46061:284;;;;;;;;;;-1:-1:-1;46061:284:0;;;;;:::i;:::-;;:::i;114447:21::-;;;;;;;;;;;;;;;;100107:164;;;;;;;;;;-1:-1:-1;100107:164:0;;;;;:::i;:::-;;:::i;45075:207::-;;;;;;;;;;-1:-1:-1;45075:207:0;;;;;:::i;:::-;;:::i;61008:388::-;;;;;;;;;;-1:-1:-1;61008:388:0;;;;;:::i;:::-;;:::i;13194:201::-;;;;;;;;;;-1:-1:-1;13194:201:0;;;;;:::i;:::-;;:::i;43997:211::-;;;;;;;;;;-1:-1:-1;43997:211:0;;;;;:::i;:::-;;:::i;59994:57::-;;;;;;;;;;-1:-1:-1;59994:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;41184:762;11084:10;41424;-1:-1:-1;;;;;41400:35:0;;41392:78;;;;-1:-1:-1;;;41392:78:0;;18566:2:1;41392:78:0;;;18548:21:1;18605:2;18585:18;;;18578:30;18644:32;18624:18;;;18617:60;18694:18;;41392:78:0;;;;;;;;;41512:32;;;41483:26;41512:32;;;:19;:32;;;;;41483:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41718:13;:20;41696:11;;:18;;:42;:70;;;;;41765:1;41742:13;:20;:24;41696:70;:124;;;;-1:-1:-1;41796:24:0;;;;;;41770:22;;;;41780:11;;;;41770:22;:::i;:::-;;;;;;;;:50;41696:124;41688:175;;;;-1:-1:-1;;;41688:175:0;;19586:2:1;41688:175:0;;;19568:21:1;19625:2;19605:18;;;19598:30;19664:34;19644:18;;;19637:62;-1:-1:-1;;;19715:18:1;;;19708:36;19761:19;;41688:175:0;19384:402:1;41688:175:0;41876:62;41895:11;41908;;41876:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41876:62:0;;;;;;;;;;;;;;;;;;;;;;41921:6;;-1:-1:-1;41876:62:0;-1:-1:-1;41929:8:0;;;;;;41876:62;;41929:8;;;;41876:62;;;;;;;;;-1:-1:-1;41876:18:0;;-1:-1:-1;;;41876:62:0:i;:::-;41315:631;41184:762;;;;;;:::o;113289:228::-;113404:4;-1:-1:-1;;;;;;113428:41:0;;;;:81;;;113473:36;113497:11;113473:23;:36::i;:::-;113421:88;113289:228;-1:-1:-1;;113289:228:0:o;98126:100::-;98180:13;98213:5;98206:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98126:100;:::o;44482:123::-;12181:13;:11;:13::i;:::-;44562:35:::1;::::0;-1:-1:-1;;;44562:35:0;;14250:6:1;14238:19;;44562:35:0::1;::::0;::::1;14220:38:1::0;44562:10:0::1;-1:-1:-1::0;;;;;44562:25:0::1;::::0;::::1;::::0;14193:18:1;;44562:35:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;44482:123:::0;:::o;99638:171::-;99714:7;99734:23;99749:7;99734:14;:23::i;:::-;-1:-1:-1;99777:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;99777:24:0;;99638:171::o;99156:416::-;99237:13;99253:23;99268:7;99253:14;:23::i;:::-;99237:39;;99301:5;-1:-1:-1;;;;;99295:11:0;:2;-1:-1:-1;;;;;99295:11:0;;99287:57;;;;-1:-1:-1;;;99287:57:0;;19993:2:1;99287:57:0;;;19975:21:1;20032:2;20012:18;;;20005:30;20071:34;20051:18;;;20044:62;-1:-1:-1;;;20122:18:1;;;20115:31;20163:19;;99287:57:0;19791:397:1;99287:57:0;11084:10;-1:-1:-1;;;;;99379:21:0;;;;:62;;-1:-1:-1;99404:37:0;99421:5;11084:10;100107:164;:::i;99404:37::-;99357:173;;;;-1:-1:-1;;;99357:173:0;;20395:2:1;99357:173:0;;;20377:21:1;20434:2;20414:18;;;20407:30;20473:34;20453:18;;;20446:62;20544:31;20524:18;;;20517:59;20593:19;;99357:173:0;20193:425:1;99357:173:0;99543:21;99552:2;99556:7;99543:8;:21::i;:::-;99226:346;99156:416;;:::o;66012:321::-;12181:13;:11;:13::i;:::-;66150:1:::1;66122:25;:29;66114:78;;;::::0;-1:-1:-1;;;66114:78:0;;20825:2:1;66114:78:0::1;::::0;::::1;20807:21:1::0;20864:2;20844:18;;;20837:30;20903:34;20883:18;;;20876:62;-1:-1:-1;;;20954:18:1;;;20947:34;20998:19;;66114:78:0::1;20623:400:1::0;66114:78:0::1;66203:24;:52:::0;;;66271:54:::1;::::0;8304:25:1;;;66271:54:0::1;::::0;8292:2:1;8277:18;66271:54:0::1;;;;;;;;66012:321:::0;:::o;46407:142::-;12181:13;:11;:13::i;:::-;46498:35:::1;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:43;46407:142::o;44613:129::-;12181:13;:11;:13::i;:::-;44696:38:::1;::::0;-1:-1:-1;;;44696:38:0;;14250:6:1;14238:19;;44696:38:0::1;::::0;::::1;14220::1::0;44696:10:0::1;-1:-1:-1::0;;;;;44696:28:0::1;::::0;::::1;::::0;14193:18:1;;44696:38:0::1;14076:188:1::0;115310:81:0;115354:29;115380:1;115354:17;:29::i;:::-;115310:81::o;100338:301::-;100499:41;11084:10;100518:12;100532:7;100499:18;:41::i;:::-;100491:99;;;;-1:-1:-1;;;100491:99:0;;;;;;;:::i;:::-;100603:28;100613:4;100619:2;100623:7;100603:9;:28::i;60680:320::-;60846:14;60862:11;60893:99;60914:11;60927:10;60939:27;60957:8;60939:17;:27::i;:::-;60968:7;60977:14;60893:20;:99::i;:::-;60886:106;;;;60680:320;;;;;;;;:::o;116533:192::-;12181:13;:11;:13::i;:::-;116608:82:::1;::::0;116590:12:::1;::::0;116616:10:::1;::::0;116654:21:::1;::::0;116590:12;116608:82;116590:12;116608:82;116654:21;116616:10;116608:82:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116589:101;;;116709:7;116701:16;;;::::0;::::1;;116578:147;116533:192::o:0;46647:250::-;46789:32;;;46743:4;46789:32;;;:19;:32;;;;;46760:61;;46743:4;;46789:32;46760:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46877:11;;46867:22;;;;;;;:::i;:::-;;;;;;;;46849:13;46839:24;;;;;;:50;46832:57;;;46647:250;;;;;:::o;100710:151::-;100814:39;100831:4;100837:2;100841:7;100814:39;;;;;;;;;;;;:16;:39::i;44750:178::-;12181:13;:11;:13::i;:::-;44865:55:::1;::::0;-1:-1:-1;;;44865:55:0;;-1:-1:-1;;;;;44865:10:0::1;:29;::::0;::::1;::::0;:55:::1;::::0;44895:11;;44908;;;;44865:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;115855:359:::0;116041:36;;;;;;;:23;:36;;;;;;115977:101;;115992:11;;59622:1;;116025:14;;115977;:101::i;:::-;116110:24;;;116121:10;116110:24;;;22434:51:1;116132:1:0;22501:18:1;;;22494:45;116110:24:0;;;;;;;;;22407:18:1;;;;116110:24:0;;;116089:117;;116097:11;;116152:4;116160:18;116180:14;116196:9;116089:7;:117::i;61404:351::-;61629:118;61635:5;61642:11;61655:10;61667:27;61685:8;61667:17;:27::i;:::-;61696:14;61712:18;61732:14;61629:5;:118::i;97836:223::-;97908:7;102569:16;;;:7;:16;;;;;;-1:-1:-1;;;;;102569:16:0;;97972:56;;;;-1:-1:-1;;;97972:56:0;;22752:2:1;97972:56:0;;;22734:21:1;22791:2;22771:18;;;22764:30;-1:-1:-1;;;22810:18:1;;;22803:54;22874:18;;97972:56:0;22550:348:1;54099:346:0;11084:10;54313:4;54289:29;54281:80;;;;-1:-1:-1;;;54281:80:0;;23105:2:1;54281:80:0;;;23087:21:1;23144:2;23124:18;;;23117:30;23183:34;23163:18;;;23156:62;-1:-1:-1;;;23234:18:1;;;23227:36;23280:19;;54281:80:0;22903:402:1;54281:80:0;54372:65;54394:11;54407;;54372:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54372:65:0;;;;;;;;;;;;;;;;;;;;;;54420:6;;-1:-1:-1;54372:65:0;-1:-1:-1;54428:8:0;;;;;;54372:65;;54428:8;;;;54372:65;;;;;;;;;-1:-1:-1;54372:21:0;;-1:-1:-1;;;54372:65:0:i;:::-;54099:346;;;;;;:::o;116733:75::-;12181:13;:11;:13::i;:::-;116790:3:::1;:10:::0;116733:75::o;115399:109::-;115466:34;115484:15;115466:17;:34::i;97567:207::-;97639:7;-1:-1:-1;;;;;97667:19:0;;97659:73;;;;-1:-1:-1;;;97659:73:0;;23512:2:1;97659:73:0;;;23494:21:1;23551:2;23531:18;;;23524:30;23590:34;23570:18;;;23563:62;-1:-1:-1;;;23641:18:1;;;23634:39;23690:19;;97659:73:0;23310:405:1;97659:73:0;-1:-1:-1;;;;;;97750:16:0;;;;;:9;:16;;;;;;;97567:207::o;12936:103::-;12181:13;:11;:13::i;:::-;13001:30:::1;13028:1;13001:18;:30::i;40596:51::-:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64222:1009::-;58587:21;:19;:21::i;:::-;64332:19;;::::1;::::0;;::::1;::::0;;;;64308:21:::1;64370:28:::0;;;:13:::1;:28:::0;;;;;;;:42:::1;;::::0;::::1;;64362:72;;;::::0;-1:-1:-1;;;64362:72:0;;23922:2:1;64362:72:0::1;::::0;::::1;23904:21:1::0;23961:2;23941:18;;;23934:30;-1:-1:-1;;;23980:18:1;;;23973:47;24037:18;;64362:72:0::1;23720:341:1::0;64362:72:0::1;64450:22;64487:8;64476:37;;;;;;;;;;;;:::i;:::-;64526:14;64555:28:::0;;;:13:::1;:28;::::0;;;;:39;;;64636:34;;::::1;::::0;64447:66;;-1:-1:-1;64526:14:0;;-1:-1:-1;64543:138:0::1;::::0;64555:39:::1;::::0;::::1;::::0;64596:38;;::::1;-1:-1:-1::0;;;;;64596:38:0::1;::::0;64447:66;64543:11:::1;:138::i;:::-;64712:28;::::0;;;:13:::1;:28;::::0;;;;:34:::1;;::::0;64526:155;;-1:-1:-1;64700:46:0;::::1;64692:100;;;::::0;-1:-1:-1;;;64692:100:0;;25823:2:1;64692:100:0::1;::::0;::::1;25805:21:1::0;25862:2;25842:18;;;25835:30;25901:34;25881:18;;;25874:62;-1:-1:-1;;;25952:18:1;;;25945:39;26001:19;;64692:100:0::1;25621:405:1::0;64692:100:0::1;64822:8;:15;64809:9;:28:::0;64805:419:::1;;64917:28;::::0;;;:13:::1;:28;::::0;;;;;64910:35;;-1:-1:-1;;;;;;64910:35:0;;;;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;64910:35:0::1;::::0;;64965:28;::::1;::::0;::::1;::::0;64931:13;8304:25:1;;8292:2;8277:18;;8158:177;64965:28:0::1;;;;;;;;64805:419;;;65102:110;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;65115:28:0;;;:13:::1;:28;::::0;;;;;;:39;;::::1;::::0;;::::1;65102:110:::0;;-1:-1:-1;;;;;65156:38:0;;;::::1;::::0;::::1;65102:110:::0;;::::1;::::0;;;;;;;;;65115:39;65102:110;;;;;;65071:28;;;;;;;;:141;;;;::::1;::::0;;::::1;-1:-1:-1::0;;;;;;65071:141:0;;;;;;::::1;::::0;;;;;;;::::1;::::0;;;;;;::::1;::::0;;;;;65156:38:::1;65071:141:::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;65071:141:0;;::::1;::::0;;;::::1;::::0;;64805:419:::1;64297:934;;;58631:20:::0;58025:1;59151:7;:22;58968:213;98295:104;98351:13;98384:7;98377:14;;;;;:::i;66857:351::-;12181:13;:11;:13::i;:::-;67009:1:::1;66983:23;:27;66975:74;;;::::0;-1:-1:-1;;;66975:74:0;;26233:2:1;66975:74:0::1;::::0;::::1;26215:21:1::0;26272:2;26252:18;;;26245:30;26311:34;26291:18;;;26284:62;-1:-1:-1;;;26362:18:1;;;26355:32;26404:19;;66975:74:0::1;26031:398:1::0;66975:74:0::1;67060:35;::::0;::::1;;::::0;;;:22:::1;:35;::::0;;;;;;;;:61;;;67137:63;;26606:38:1;;;26660:18;;26653:34;;;67137:63:0::1;::::0;26579:18:1;67137:63:0::1;;;;;;;;66857:351:::0;;:::o;45579:330::-;45703:35;;;45683:17;45703:35;;;:19;:35;;;;;45683:55;;45658:12;;45683:17;45703:35;45683:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45757:4;:11;45772:1;45757:16;45749:58;;;;-1:-1:-1;;;45749:58:0;;26900:2:1;45749:58:0;;;26882:21:1;26939:2;26919:18;;;26912:30;26978:31;26958:18;;;26951:59;27027:18;;45749:58:0;26698:353:1;45749:58:0;45825:31;45836:1;45853:2;45839:4;:11;:16;;;;:::i;:::-;45825:4;;:31;:10;:31::i;:::-;45818:38;45579:330;-1:-1:-1;;;45579:330:0:o;99881:155::-;99976:52;11084:10;100009:8;100019;99976:18;:52::i;:::-;99881:155;;:::o;45290:281::-;12181:13;:11;:13::i;:::-;45462:14:::1;;45486:4;45445:47;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;45445:47:0;;::::1;::::0;;;;;;45407:35:::1;::::0;::::1;;::::0;;;:19:::1;45445:47;45407:35:::0;;;:85:::1;::::0;:35;:85:::1;:::i;:::-;;45508:55;45532:14;45548;;45508:55;;;;;;;;:::i;:::-;;;;;;;;45290:281:::0;;;:::o;61763:348::-;62003:100;62009:5;62016:11;62029:10;62041:9;62052:14;62068:18;62088:14;62003:5;:100::i;100932:279::-;101063:41;11084:10;101096:7;101063:18;:41::i;:::-;101055:99;;;;-1:-1:-1;;;101055:99:0;;;;;;;:::i;:::-;101165:38;101179:4;101185:2;101189:7;101198:4;101165:13;:38::i;:::-;100932:279;;;;:::o;45917:136::-;12181:13;:11;:13::i;:::-;45987:8:::1;:20:::0;;-1:-1:-1;;;;;;45987:20:0::1;-1:-1:-1::0;;;;;45987:20:0;::::1;::::0;;::::1;::::0;;;46023:22:::1;::::0;3427:51:1;;;46023:22:0::1;::::0;3415:2:1;3400:18;46023:22:0::1;3281:203:1::0;116222:166:0;116290:13;116346:10;:8;:10::i;:::-;116358:20;116375:2;116358:16;:20::i;:::-;116329:50;;;;;;;;;:::i;:::-;;;;;;;;;;;;;116315:65;;116222:166;;;:::o;44270:204::-;12181:13;:11;:13::i;:::-;44404:62:::1;::::0;-1:-1:-1;;;44404:62:0;;-1:-1:-1;;;;;44404:10:0::1;:20;::::0;::::1;::::0;:62:::1;::::0;44425:8;;44435;;44445:11;;44458:7;;;;44404:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;44270:204:::0;;;;;:::o;66434:359::-;12181:13;:11;:13::i;:::-;66589:1:::1;66562:24;:28;66554:76;;;::::0;-1:-1:-1;;;66554:76:0;;31090:2:1;66554:76:0::1;::::0;::::1;31072:21:1::0;31129:2;31109:18;;;31102:30;31168:34;31148:18;;;31141:62;-1:-1:-1;;;31219:18:1;;;31212:33;31262:19;;66554:76:0::1;30888:399:1::0;66554:76:0::1;66641:36;::::0;::::1;;::::0;;;:23:::1;:36;::::0;;;;;;;;:63;;;66720:65;;26606:38:1;;;26660:18;;26653:34;;;66720:65:0::1;::::0;26579:18:1;66720:65:0::1;26434:259:1::0;54631:767:0;54842:27;;;54820:19;54842:27;;;:14;:27;;;;;;:40;;;;54870:11;;;;54842:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54842:48:0;;;;;;;;;;;;-1:-1:-1;54842:48:0;54901:73;;;;-1:-1:-1;;;54901:73:0;;31494:2:1;54901:73:0;;;31476:21:1;31533:2;31513:18;;;31506:30;31572:34;31552:18;;;31545:62;-1:-1:-1;;;31623:18:1;;;31616:33;31666:19;;54901:73:0;31292:399:1;54901:73:0;55016:11;55003:8;;54993:19;;;;;;;:::i;:::-;;;;;;;;:34;54985:80;;;;-1:-1:-1;;;54985:80:0;;31898:2:1;54985:80:0;;;31880:21:1;31937:2;31917:18;;;31910:30;31976:34;31956:18;;;31949:62;-1:-1:-1;;;32027:18:1;;;32020:31;32068:19;;54985:80:0;31696:397:1;54985:80:0;55113:27;;;55172:1;55113:27;;;:14;:27;;;;;;:40;;;;55141:11;;;;55113:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55113:48:0;;;;;;;;;;;;:61;;;;55243:65;;;;;;;;;;;;;;;;;;;55265:11;;55278;;55243:65;;;;;;55278:11;55243:65;;55278:11;55243:65;;;;;;;;;-1:-1:-1;;55243:65:0;;;;;;;;;;;;;;;;;;;;;;55291:6;;-1:-1:-1;55243:65:0;-1:-1:-1;55299:8:0;;;;;;55243:65;;55299:8;;;;55243:65;;;;;;;;;-1:-1:-1;55243:21:0;;-1:-1:-1;;;55243:65:0:i;:::-;55324:66;55344:11;55357;;55370:6;55378:11;55324:66;;;;;;;;;;:::i;:::-;;;;;;;;54764:634;54631:767;;;;;;:::o;115518:329::-;115703:24;;;115714:10;115703:24;;;22434:51:1;115640:14:0;22501:18:1;;;22494:45;;;115703:24:0;;;;;;;;;22407:18:1;;;115703:24:0;;;;-1:-1:-1;;;115745:94:0;;;115640:14;;;115745:10;-1:-1:-1;;;;;115745:23:0;;;;:94;;115769:11;;115798:4;;115703:24;;115815:7;;115824:14;;115745:94;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115738:101;;;;;115518:329;;;;;;:::o;46061:284::-;12181:13;:11;:13::i;:::-;46185:1:::1;46175:7;:11;46167:45;;;::::0;-1:-1:-1;;;46167:45:0;;33703:2:1;46167:45:0::1;::::0;::::1;33685:21:1::0;33742:2;33722:18;;;33715:30;-1:-1:-1;;;33761:18:1;;;33754:51;33822:18;;46167:45:0::1;33501:345:1::0;46167:45:0::1;46223:28;::::0;;::::1;;::::0;;;:15:::1;:28;::::0;;;;;;;:41;;::::1;::::0;;;;;;;;;;:51;;;46290:47;;34074:34:1;;;34124:18;;34117:43;;;;34176:18;;;34169:34;;;46290:47:0::1;::::0;34037:2:1;34022:18;46290:47:0::1;33851:358:1::0;100107:164:0;-1:-1:-1;;;;;100228:25:0;;;100204:4;100228:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;100107:164::o;45075:207::-;12181:13;:11;:13::i;:::-;45176:35:::1;::::0;::::1;;::::0;;;:19:::1;:35;::::0;;;;:43:::1;45214:5:::0;;45176:35;:43:::1;:::i;:::-;;45235:39;45252:14;45268:5;;45235:39;;;;;;;;:::i;61008:388::-:0;61189:14;61205:11;61229:20;61263:10;61275:9;61252:33;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;61252:33:0;;;;;;;;;;-1:-1:-1;;;61303:85:0;;61252:33;-1:-1:-1;;;;;;61303:10:0;:23;;;;:85;;61327:11;;61348:4;;61252:33;;61364:7;;61373:14;;61303:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61296:92;;;;;61008:388;;;;;;;;:::o;13194:201::-;12181:13;:11;:13::i;:::-;-1:-1:-1;;;;;13283:22:0;::::1;13275:73;;;::::0;-1:-1:-1;;;13275:73:0;;37137:2:1;13275:73:0::1;::::0;::::1;37119:21:1::0;37176:2;37156:18;;;37149:30;37215:34;37195:18;;;37188:62;-1:-1:-1;;;37266:18:1;;;37259:36;37312:19;;13275:73:0::1;36935:402:1::0;13275:73:0::1;13359:28;13378:8;13359:18;:28::i;43997:211::-:0;44132:68;;-1:-1:-1;;;44132:68:0;;37579:6:1;37612:15;;;44132:68:0;;;37594:34:1;37664:15;;37644:18;;;37637:43;44181:4:0;37696:18:1;;;37689:60;37765:18;;;37758:34;;;44100:12:0;;44132:10;-1:-1:-1;;;;;44132:20:0;;;;37541:19:1;;44132:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44132:68:0;;;;;;;;;;;;:::i;:::-;44125:75;;43997:211;;;;;;;:::o;53246:514::-;53396:12;53410:19;53433:153;53467:9;53478:3;53506:34;;;53542:11;53555;53568:6;53576:8;53483:102;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;53483:102:0;;;;;;;;;;;;;;-1:-1:-1;;;;;53483:102:0;-1:-1:-1;;;;;;53483:102:0;;;;;;;;;;53441:4;;53433:153;;:33;:153::i;:::-;53395:191;;;;53646:7;53641:112;;53670:71;53690:11;53703;53716:6;53724:8;53734:6;53670:19;:71::i;97198:305::-;97300:4;-1:-1:-1;;;;;;97337:40:0;;-1:-1:-1;;;97337:40:0;;:105;;-1:-1:-1;;;;;;;97394:48:0;;-1:-1:-1;;;97394:48:0;97337:105;:158;;;;97459:36;97483:11;97459:23;:36::i;12460:132::-;12341:7;12368:6;-1:-1:-1;;;;;12368:6:0;11084:10;12524:23;12516:68;;;;-1:-1:-1;;;12516:68:0;;38907:2:1;12516:68:0;;;38889:21:1;;;38926:18;;;38919:30;38985:34;38965:18;;;38958:62;39037:18;;12516:68:0;38705:356:1;109201:135:0;109283:16;109291:7;109283;:16::i;:::-;109275:53;;;;-1:-1:-1;;;109275:53:0;;22752:2:1;109275:53:0;;;22734:21:1;22791:2;22771:18;;;22764:30;-1:-1:-1;;;22810:18:1;;;22803:54;22874:18;;109275:53:0;22550:348:1;108514:174:0;108589:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;108589:29:0;-1:-1:-1;;;;;108589:29:0;;;;;;;;:24;;108643:23;108589:24;108643:14;:23::i;:::-;-1:-1:-1;;;;;108634:46:0;;;;;;;;;;;108514:174;;:::o;114887:413::-;114980:3;;114967:9;:16;;114959:47;;;;-1:-1:-1;;;114959:47:0;;39268:2:1;114959:47:0;;;39250:21:1;39307:2;39287:18;;;39280:30;-1:-1:-1;;;39326:18:1;;;39319:48;39384:18;;114959:47:0;39066:342:1;114959:47:0;115039:9;;115025:10;;:23;;115017:49;;;;-1:-1:-1;;;115017:49:0;;39615:2:1;115017:49:0;;;39597:21:1;39654:2;39634:18;;;39627:30;-1:-1:-1;;;39673:18:1;;;39666:43;39726:18;;115017:49:0;39413:337:1;115017:49:0;115092:10;;;;;;115079;115113:12;115092:10;115113:12;:::i;:::-;;;;;;115138:28;115148:10;115160:5;115138:9;:28::i;:::-;-1:-1:-1;;;;;115182:29:0;;;115178:115;;115233:48;;;40069:25:1;;;-1:-1:-1;;;;;40130:32:1;;40125:2;40110:18;;40103:60;115246:10:0;;115233:48;;40042:18:1;115233:48:0;;;;;;;114948:352;114887:413;:::o;103201:264::-;103294:4;103311:13;103327:23;103342:7;103327:14;:23::i;:::-;103311:39;;103380:5;-1:-1:-1;;;;;103369:16:0;:7;-1:-1:-1;;;;;103369:16:0;;:52;;;;103389:32;103406:5;103413:7;103389:16;:32::i;:::-;103369:87;;;;103449:7;-1:-1:-1;;;;;103425:31:0;:20;103437:7;103425:11;:20::i;:::-;-1:-1:-1;;;;;103425:31:0;;103361:96;103201:264;-1:-1:-1;;;;103201:264:0:o;107166:1229::-;107291:4;-1:-1:-1;;;;;107264:31:0;:23;107279:7;107264:14;:23::i;:::-;-1:-1:-1;;;;;107264:31:0;;107256:81;;;;-1:-1:-1;;;107256:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;107356:16:0;;107348:65;;;;-1:-1:-1;;;107348:65:0;;40782:2:1;107348:65:0;;;40764:21:1;40821:2;40801:18;;;40794:30;40860:34;40840:18;;;40833:62;-1:-1:-1;;;40911:18:1;;;40904:34;40955:19;;107348:65:0;40580:400:1;107348:65:0;107598:4;-1:-1:-1;;;;;107571:31:0;:23;107586:7;107571:14;:23::i;:::-;-1:-1:-1;;;;;107571:31:0;;107563:81;;;;-1:-1:-1;;;107563:81:0;;;;;;;:::i;:::-;107716:24;;;;:15;:24;;;;;;;;107709:31;;-1:-1:-1;;;;;;107709:31:0;;;;;;-1:-1:-1;;;;;108192:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;108192:20:0;;;108227:13;;;;;;;;;:18;;107709:31;108227:18;;;108267:16;;;:7;:16;;;;;;:21;;;;;;;;;;108306:27;;107732:7;;108306:27;;;99226:346;99156:416;;:::o;67435:185::-;67547:13;;;67558:1;67547:13;;;;;;;;;67499;;67525:19;;67547:13;;;;;;;;;;;;-1:-1:-1;67547:13:0;67525:35;;67582:7;67571:5;67577:1;67571:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;67607:5;67435:185;-1:-1:-1;;67435:185:0:o;42796:420::-;42932:21;42956:28;42969:14;42956:12;:28::i;:::-;43014;;;;42995:16;43014:28;;;:15;:28;;;;;;;;:35;;;;;;;;;;;;42932:52;;-1:-1:-1;42995:16:0;43014:47;;43052:9;;43014:47;:::i;:::-;42995:66;;43094:1;43080:11;:15;43072:54;;;;-1:-1:-1;;;43072:54:0;;41449:2:1;43072:54:0;;;41431:21:1;41488:2;41468:18;;;41461:30;41527:28;41507:18;;;41500:56;41573:18;;43072:54:0;41247:350:1;43072:54:0;43165:11;43145:16;:31;;43137:71;;;;-1:-1:-1;;;43137:71:0;;41804:2:1;43137:71:0;;;41786:21:1;41843:2;41823:18;;;41816:30;41882:29;41862:18;;;41855:57;41929:18;;43137:71:0;41602:351:1;42235:553:0;42458:32;;;42429:26;42458:32;;;:19;:32;;;;;42429:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42509:13;:20;42533:1;42509:25;42501:86;;;;-1:-1:-1;;;42501:86:0;;42160:2:1;42501:86:0;;;42142:21:1;42199:2;42179:18;;;42172:30;42238:34;42218:18;;;42211:62;-1:-1:-1;;;42289:18:1;;;42282:46;42345:19;;42501:86:0;41958:412:1;42501:86:0;42598:47;42616:11;42629:8;:15;42598:17;:47::i;:::-;42656:124;;-1:-1:-1;;;42656:124:0;;-1:-1:-1;;;;;42656:10:0;:15;;;;42679:10;;42656:124;;42691:11;;42704:13;;42719:8;;42729:14;;42745:18;;42765:14;;42656:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42418:370;42235:553;;;;;;:::o;62119:960::-;62394:1;62375:9;:16;:20;62367:52;;;;-1:-1:-1;;;62367:52:0;;43422:2:1;62367:52:0;;;43404:21:1;43461:2;43441:18;;;43434:30;-1:-1:-1;;;43480:18:1;;;43473:49;43539:18;;62367:52:0;43220:343:1;62367:52:0;62438:9;:16;62458:1;62438:21;:80;;;-1:-1:-1;62483:35:0;;;;;;;:22;:35;;;;;;62463:16;;:55;;62438:80;62430:127;;;;-1:-1:-1;;;62430:127:0;;43770:2:1;62430:127:0;;;43752:21:1;43809:2;43789:18;;;43782:30;43848:34;43828:18;;;43821:62;-1:-1:-1;;;43899:18:1;;;43892:32;43941:19;;62430:127:0;43568:398:1;62430:127:0;62575:6;62570:127;62591:9;:16;62587:1;:20;62570:127;;;62629:56;62640:5;62647:11;62660:10;62672:9;62682:1;62672:12;;;;;;;;:::i;:::-;;;;;;;62629:10;:56::i;:::-;62609:3;;;;:::i;:::-;;;;62570:127;;;;62709:20;62743:10;62755:9;62732:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;62709:56;;62778:120;62793:11;59622:1;62826:14;62881:9;:16;62842:23;:36;62866:11;62842:36;;;;;;;;;;;;;;;;:55;;;;:::i;:::-;62778:14;:120::i;:::-;62909:92;62917:11;62930:7;62939:14;62955:18;62975:14;62991:9;62909:7;:92::i;:::-;63049:10;63017:54;;;;;;:::i;:::-;;;;;;;;63042:5;-1:-1:-1;;;;;63017:54:0;63029:11;63017:54;;;63061:9;63017:54;;;;;;:::i;:::-;;;;;;;;62325:754;62119:960;;;;;;;:::o;63087:1037::-;63329:27;63358:22;63395:8;63384:37;;;;;;;;;;;;:::i;:::-;63328:93;;;;63437:8;63446:1;63437:11;;;;;;;;:::i;:::-;;;;;;;63450:1;63437:14;63434:51;;63467:7;;;;63434:51;63586:2;63566:23;;63560:30;63495:17;63630:48;63642:11;63560:30;63495:17;63669:8;63630:11;:48::i;:::-;63613:65;;63705:8;:15;63693:9;:27;63689:347;;;63849:19;;;;;;;;;;63914:53;;;;;;;;;;;;;;-1:-1:-1;;;;;63914:53:0;;;;;;;;;;;;;;;63962:4;63914:53;;;;;;63825:21;63883:28;;;:13;:28;;;;;;;:84;;;;;;;;;;;-1:-1:-1;;;;;;63883:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63883:84:0;;;;;;;;;;63987:37;;;;;;63849:19;;63859:8;;63987:37;:::i;:::-;;;;;;;;63722:314;63689:347;64096:9;-1:-1:-1;;;;;64053:63:0;64083:11;64053:63;;;;;;:::i;:::-;;;;;;;;64070:11;64053:63;;;64107:8;64053:63;;;;;;:::i;13555:191::-;13629:16;13648:6;;-1:-1:-1;;;;;13665:17:0;;;-1:-1:-1;;;;;;13665:17:0;;;;;;13698:40;;13648:6;;;;;;;13698:40;;13629:16;13698:40;13618:128;13555:191;:::o;58667:293::-;58069:1;58801:7;;:19;58793:63;;;;-1:-1:-1;;;58793:63:0;;45198:2:1;58793:63:0;;;45180:21:1;45237:2;45217:18;;;45210:30;45276:33;45256:18;;;45249:61;45327:18;;58793:63:0;44996:355:1;58793:63:0;58069:1;58934:7;:18;58667:293::o;65430:574::-;65552:7;65580:11;65602:263;65613:9;:16;65609:1;:20;65602:263;;;65739:24;;65727:9;:36;65765:5;65723:47;65787:48;65797:11;65810:10;65822:9;65832:1;65822:12;;;;;;;;:::i;:::-;;;;;;;65787:9;:48::i;:::-;65850:3;;;;:::i;:::-;;;;65602:263;;30304:2779;30445:12;30499:7;30483:12;30499:7;30493:2;30483:12;:::i;:::-;:23;;30475:50;;;;-1:-1:-1;;;30475:50:0;;45558:2:1;30475:50:0;;;45540:21:1;45597:2;45577:18;;;45570:30;-1:-1:-1;;;45616:18:1;;;45609:44;45670:18;;30475:50:0;45356:338:1;30475:50:0;30561:16;30570:7;30561:6;:16;:::i;:::-;30544:6;:13;:33;;30536:63;;;;-1:-1:-1;;;30536:63:0;;45901:2:1;30536:63:0;;;45883:21:1;45940:2;45920:18;;;45913:30;-1:-1:-1;;;45959:18:1;;;45952:47;46016:18;;30536:63:0;45699:341:1;30536:63:0;30612:22;30678:15;;30707:1933;;;;32784:4;32778:11;32765:24;;32965:1;32954:9;32947:20;33015:4;33004:9;33000:20;32994:4;32987:34;30671:2365;;30707:1933;30884:4;30878:11;30865:24;;31521:2;31512:7;31508:16;31893:9;31886:17;31880:4;31876:28;31864:9;31853;31849:25;31845:60;31942:7;31938:2;31934:16;32191:6;32177:9;32170:17;32164:4;32160:28;32148:9;32140:6;32136:22;32132:57;32128:70;31970:426;32225:3;32221:2;32218:11;31970:426;;;32367:9;;32356:21;;32267:4;32259:13;;;;32300;31970:426;;;-1:-1:-1;;32416:26:0;;;32620:2;32603:11;-1:-1:-1;;32599:25:0;32593:4;32586:39;-1:-1:-1;30671:2365:0;-1:-1:-1;33066:9:0;30304:2779;-1:-1:-1;;;;30304:2779:0:o;108831:281::-;108952:8;-1:-1:-1;;;;;108943:17:0;:5;-1:-1:-1;;;;;108943:17:0;;108935:55;;;;-1:-1:-1;;;108935:55:0;;46247:2:1;108935:55:0;;;46229:21:1;46286:2;46266:18;;;46259:30;46325:27;46305:18;;;46298:55;46370:18;;108935:55:0;46045:349:1;108935:55:0;-1:-1:-1;;;;;109001:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;109001:46:0;;;;;;;;;;109063:41;;2099::1;;;109063::0;;2072:18:1;109063:41:0;;;;;;;108831:281;;;:::o;102092:270::-;102205:28;102215:4;102221:2;102225:7;102205:9;:28::i;:::-;102252:47;102275:4;102281:2;102285:7;102294:4;102252:22;:47::i;:::-;102244:110;;;;-1:-1:-1;;;102244:110:0;;;;;;;:::i;116396:129::-;116448:13;116474:43;;;;;;;;;;;;;;;;;;;116396:129;:::o;93569:716::-;93625:13;93676:14;93693:17;93704:5;93693:10;:17::i;:::-;93713:1;93693:21;93676:38;;93729:20;93763:6;-1:-1:-1;;;;;93752:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;93752:18:0;-1:-1:-1;93729:41:0;-1:-1:-1;93894:28:0;;;93910:2;93894:28;93951:288;-1:-1:-1;;93983:5:0;-1:-1:-1;;;94120:2:0;94109:14;;94104:30;93983:5;94091:44;94181:2;94172:11;;;-1:-1:-1;94202:21:0;93951:288;94202:21;-1:-1:-1;94260:6:0;93569:716;-1:-1:-1;;;93569:716:0:o;47969:1275::-;48131:4;48137:12;48199:15;48225:13;48249:24;48286:8;48276:19;;-1:-1:-1;;;;;48276:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48276:19:0;;48249:46;;48777:1;48751;48717:9;48711:16;48682:4;48671:9;48667:20;48636:1;48601:7;48575:4;48556:247;48544:259;;48868:16;48857:27;;48913:8;48904:7;48901:21;48898:78;;;48953:8;48942:19;;48898:78;49059:7;49046:11;49039:28;49177:7;49174:1;49167:4;49154:11;49150:22;49135:50;49214:8;;;;-1:-1:-1;47969:1275:0;-1:-1:-1;;;;;;47969:1275:0:o;53768:323::-;53992:8;53982:19;;;;;;53931:14;:27;53946:11;53931:27;;;;;;;;;;;;;;;53959:11;53931:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;53931:48:0;;;;;;;;;:70;;;;54017:66;;;;54031:11;;54044;;53972:6;;54065:8;;54075:7;;54017:66;:::i;:::-;;;;;;;;53768:323;;;;;:::o;60453:219::-;60555:4;-1:-1:-1;;;;;;60579:45:0;;-1:-1:-1;;;60579:45:0;;:85;;-1:-1:-1;;;;;;;;;;56281:40:0;;;60628:36;56172:157;102906:128;102971:4;102569:16;;;:7;:16;;;;;;-1:-1:-1;;;;;102569:16:0;102995:31;;;102906:128::o;103807:110::-;103883:26;103893:2;103897:7;103883:26;;;;;;;;;;;;:9;:26::i;43224:271::-;43306:13;43365:2;43340:14;:21;:27;;43332:68;;;;-1:-1:-1;;;43332:68:0;;47876:2:1;43332:68:0;;;47858:21:1;47915:2;47895:18;;;47888:30;47954;47934:18;;;47927:58;48002:18;;43332:68:0;47674:352:1;43332:68:0;-1:-1:-1;43473:2:0;43453:23;43447:30;;43224:271::o;43503:389::-;43626:35;;;43602:21;43626:35;;;:22;:35;;;;;;;43676:21;;;43672:125;;-1:-1:-1;40529:5:0;43672:125;43831:16;43815:12;:32;;43807:77;;;;-1:-1:-1;;;43807:77:0;;48233:2:1;43807:77:0;;;48215:21:1;;;48252:18;;;48245:30;48311:34;48291:18;;;48284:62;48363:18;;43807:77:0;48031:356:1;113525:361:0;113642:42;11084:10;113661:12;11004:98;113642:42;113634:101;;;;-1:-1:-1;;;113634:101:0;;48594:2:1;113634:101:0;;;48576:21:1;48633:2;48613:18;;;48606:30;48672:34;48652:18;;;48645:62;-1:-1:-1;;;48723:18:1;;;48716:44;48777:19;;113634:101:0;48392:410:1;113634:101:0;113782:5;-1:-1:-1;;;;;113754:33:0;:24;113769:8;113754:14;:24::i;:::-;-1:-1:-1;;;;;113754:33:0;;113746:80;;;;-1:-1:-1;;;113746:80:0;;49009:2:1;113746:80:0;;;48991:21:1;49048:2;49028:18;;;49021:30;49087:34;49067:18;;;49060:62;-1:-1:-1;;;49138:18:1;;;49131:32;49180:19;;113746:80:0;48807:398:1;113746:80:0;113837:41;113847:5;113862:4;113869:8;113837:9;:41::i;113894:373::-;114002:17;114010:8;114002:7;:17::i;:::-;114001:18;:86;;;;114024:17;114032:8;114024:7;:17::i;:::-;:62;;;;-1:-1:-1;114081:4:0;114045:24;114060:8;114045:14;:24::i;:::-;-1:-1:-1;;;;;114045:41:0;;114024:62;113993:95;;;;;;114104:17;114112:8;114104:7;:17::i;:::-;114099:161;;114138:31;114148:10;114160:8;114138:9;:31::i;114099:161::-;114202:46;114220:4;114227:10;114239:8;114202:9;:46::i;109900:853::-;110054:4;-1:-1:-1;;;;;110075:13:0;;71048:19;:23;110071:675;;110111:71;;-1:-1:-1;;;110111:71:0;;-1:-1:-1;;;;;110111:36:0;;;;;:71;;11084:10;;110162:4;;110168:7;;110177:4;;110111:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;110111:71:0;;;;;;;;-1:-1:-1;;110111:71:0;;;;;;;;;;;;:::i;:::-;;;110107:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110352:6;:13;110369:1;110352:18;110348:328;;110395:60;;-1:-1:-1;;;110395:60:0;;;;;;;:::i;110348:328::-;110626:6;110620:13;110611:6;110607:2;110603:15;110596:38;110107:584;-1:-1:-1;;;;;;110233:51:0;-1:-1:-1;;;110233:51:0;;-1:-1:-1;110226:58:0;;110071:675;-1:-1:-1;110730:4:0;110723:11;;89313:948;89366:7;;-1:-1:-1;;;89444:17:0;;89440:106;;-1:-1:-1;;;89482:17:0;;;-1:-1:-1;89528:2:0;89518:12;89440:106;89573:8;89564:5;:17;89560:106;;89611:8;89602:17;;;-1:-1:-1;89648:2:0;89638:12;89560:106;89693:8;89684:5;:17;89680:106;;89731:8;89722:17;;;-1:-1:-1;89768:2:0;89758:12;89680:106;89813:7;89804:5;:16;89800:103;;89850:7;89841:16;;;-1:-1:-1;89886:1:0;89876:11;89800:103;89930:7;89921:5;:16;89917:103;;89967:7;89958:16;;;-1:-1:-1;90003:1:0;89993:11;89917:103;90047:7;90038:5;:16;90034:103;;90084:7;90075:16;;;-1:-1:-1;90120:1:0;90110:11;90034:103;90164:7;90155:5;:16;90151:68;;90202:1;90192:11;90247:6;89313:948;-1:-1:-1;;89313:948:0:o;104144:285::-;104239:18;104245:2;104249:7;104239:5;:18::i;:::-;104290:53;104321:1;104325:2;104329:7;104338:4;104290:22;:53::i;:::-;104268:153;;;;-1:-1:-1;;;104268:153:0;;;;;;;:::i;104765:942::-;-1:-1:-1;;;;;104845:16:0;;104837:61;;;;-1:-1:-1;;;104837:61:0;;50160:2:1;104837:61:0;;;50142:21:1;;;50179:18;;;50172:30;50238:34;50218:18;;;50211:62;50290:18;;104837:61:0;49958:356:1;104837:61:0;104918:16;104926:7;104918;:16::i;:::-;104917:17;104909:58;;;;-1:-1:-1;;;104909:58:0;;50521:2:1;104909:58:0;;;50503:21:1;50560:2;50540:18;;;50533:30;50599;50579:18;;;50572:58;50647:18;;104909:58:0;50319:352:1;104909:58:0;105127:16;105135:7;105127;:16::i;:::-;105126:17;105118:58;;;;-1:-1:-1;;;105118:58:0;;50521:2:1;105118:58:0;;;50503:21:1;50560:2;50540:18;;;50533:30;50599;50579:18;;;50572:58;50647:18;;105118:58:0;50319:352:1;105118:58:0;-1:-1:-1;;;;;105525:13:0;;;;;;:9;:13;;;;;;;;:18;;105542:1;105525:18;;;105567:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;105567:21:0;;;;;105606:33;105575:7;;105525:13;;105606:33;;105525:13;;105606:33;99881:155;;:::o;14:159:1:-;81:20;;141:6;130:18;;120:29;;110:57;;163:1;160;153:12;110:57;14:159;;;:::o;178:347::-;229:8;239:6;293:3;286:4;278:6;274:17;270:27;260:55;;311:1;308;301:12;260:55;-1:-1:-1;334:20:1;;-1:-1:-1;;;;;366:30:1;;363:50;;;409:1;406;399:12;363:50;446:4;438:6;434:17;422:29;;498:3;491:4;482:6;474;470:19;466:30;463:39;460:59;;;515:1;512;505:12;460:59;178:347;;;;;:::o;530:171::-;597:20;;-1:-1:-1;;;;;646:30:1;;636:41;;626:69;;691:1;688;681:12;706:862;812:6;820;828;836;844;852;905:3;893:9;884:7;880:23;876:33;873:53;;;922:1;919;912:12;873:53;945:28;963:9;945:28;:::i;:::-;935:38;;1024:2;1013:9;1009:18;996:32;-1:-1:-1;;;;;1088:2:1;1080:6;1077:14;1074:34;;;1104:1;1101;1094:12;1074:34;1143:58;1193:7;1184:6;1173:9;1169:22;1143:58;:::i;:::-;1220:8;;-1:-1:-1;1117:84:1;-1:-1:-1;1117:84:1;;-1:-1:-1;1274:37:1;1307:2;1292:18;;1274:37;:::i;:::-;1264:47;;1364:2;1353:9;1349:18;1336:32;1320:48;;1393:2;1383:8;1380:16;1377:36;;;1409:1;1406;1399:12;1377:36;;1448:60;1500:7;1489:8;1478:9;1474:24;1448:60;:::i;:::-;706:862;;;;-1:-1:-1;706:862:1;;-1:-1:-1;706:862:1;;1527:8;;706:862;-1:-1:-1;;;706:862:1:o;1573:131::-;-1:-1:-1;;;;;;1647:32:1;;1637:43;;1627:71;;1694:1;1691;1684:12;1709:245;1767:6;1820:2;1808:9;1799:7;1795:23;1791:32;1788:52;;;1836:1;1833;1826:12;1788:52;1875:9;1862:23;1894:30;1918:5;1894:30;:::i;2151: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:252::-;4151:6;4159;4212:2;4200:9;4191:7;4187:23;4183:32;4180:52;;;4228:1;4225;4218:12;4180:52;4251:28;4269:9;4251:28;:::i;4969:456::-;5046:6;5054;5062;5115:2;5103:9;5094:7;5090:23;5086:32;5083:52;;;5131:1;5128;5121:12;5083:52;5170:9;5157:23;5189:31;5214:5;5189:31;:::i;:::-;5239:5;-1:-1:-1;5296:2:1;5281:18;;5268:32;5309:33;5268:32;5309:33;:::i;:::-;4969:456;;5361:7;;-1:-1:-1;;;5415:2:1;5400:18;;;;5387:32;;4969:456::o;5430:127::-;5491:10;5486:3;5482:20;5479:1;5472:31;5522:4;5519:1;5512:15;5546:4;5543:1;5536:15;5562:275;5633:2;5627:9;5698:2;5679:13;;-1:-1:-1;;5675:27:1;5663:40;;-1:-1:-1;;;;;5718:34:1;;5754:22;;;5715:62;5712:88;;;5780:18;;:::i;:::-;5816:2;5809:22;5562:275;;-1:-1:-1;5562:275:1:o;5842:186::-;5890:4;-1:-1:-1;;;;;5915:6:1;5912:30;5909:56;;;5945:18;;:::i;:::-;-1:-1:-1;6011:2:1;5990:15;-1:-1:-1;;5986:29:1;6017:4;5982:40;;5842:186::o;6033:462::-;6075:5;6128:3;6121:4;6113:6;6109:17;6105:27;6095:55;;6146:1;6143;6136:12;6095:55;6182:6;6169:20;6213:48;6229:31;6257:2;6229:31;:::i;:::-;6213:48;:::i;:::-;6286:2;6277:7;6270:19;6332:3;6325:4;6320:2;6312:6;6308:15;6304:26;6301:35;6298:55;;;6349:1;6346;6339:12;6298:55;6414:2;6407:4;6399:6;6395:17;6388:4;6379:7;6375:18;6362:55;6462:1;6437:16;;;6455:4;6433:27;6426:38;;;;6441:7;6033:462;-1:-1:-1;;;6033:462:1:o;6500:160::-;6565:20;;6621:13;;6614:21;6604:32;;6594:60;;6650:1;6647;6640:12;6665:749;6774:6;6782;6790;6798;6806;6859:3;6847:9;6838:7;6834:23;6830:33;6827:53;;;6876:1;6873;6866:12;6827:53;6899:28;6917:9;6899:28;:::i;:::-;6889:38;;6978:2;6967:9;6963:18;6950:32;-1:-1:-1;;;;;7042:2:1;7034:6;7031:14;7028:34;;;7058:1;7055;7048:12;7028:34;7081:49;7122:7;7113:6;7102:9;7098:22;7081:49;:::i;:::-;7071:59;;7177:2;7166:9;7162:18;7149:32;7139:42;;7200:35;7231:2;7220:9;7216:18;7200:35;:::i;:::-;7190:45;;7288:3;7277:9;7273:19;7260:33;7244:49;;7318:2;7308:8;7305:16;7302:36;;;7334:1;7331;7324:12;7302:36;;7357:51;7400:7;7389:8;7378:9;7374:24;7357:51;:::i;:::-;7347:61;;;6665:749;;;;;;;;:::o;7672:481::-;7750:6;7758;7766;7819:2;7807:9;7798:7;7794:23;7790:32;7787:52;;;7835:1;7832;7825:12;7787:52;7858:28;7876:9;7858:28;:::i;:::-;7848:38;;7937:2;7926:9;7922:18;7909:32;-1:-1:-1;;;;;7956:6:1;7953:30;7950:50;;;7996:1;7993;7986:12;7950:50;8035:58;8085:7;8076:6;8065:9;8061:22;8035:58;:::i;:::-;7672:481;;8112:8;;-1:-1:-1;8009:84:1;;-1:-1:-1;;;;7672:481:1:o;8340:527::-;8425:6;8433;8441;8494:2;8482:9;8473:7;8469:23;8465:32;8462:52;;;8510:1;8507;8500:12;8462:52;8533:28;8551:9;8533:28;:::i;:::-;8523:38;;8611:2;8600:9;8596:18;8583:32;8624:31;8649:5;8624:31;:::i;:::-;8674:5;-1:-1:-1;8730:2:1;8715:18;;8702:32;-1:-1:-1;;;;;8746:30:1;;8743:50;;;8789:1;8786;8779:12;8743:50;8812:49;8853:7;8844:6;8833:9;8829:22;8812:49;:::i;:::-;8802:59;;;8340:527;;;;;:::o;8872:1108::-;9010:6;9018;9026;9034;9042;9050;9058;9111:3;9099:9;9090:7;9086:23;9082:33;9079:53;;;9128:1;9125;9118:12;9079:53;9167:9;9154:23;9186:31;9211:5;9186:31;:::i;:::-;9236:5;-1:-1:-1;9260:37:1;9293:2;9278:18;;9260:37;:::i;:::-;9250:47;;9348:2;9337:9;9333:18;9320:32;-1:-1:-1;;;;;9412:2:1;9404:6;9401:14;9398:34;;;9428:1;9425;9418:12;9398:34;9451:49;9492:7;9483:6;9472:9;9468:22;9451:49;:::i;:::-;9441:59;;9547:2;9536:9;9532:18;9519:32;9509:42;;9603:3;9592:9;9588:19;9575:33;9560:48;;9617:33;9642:7;9617:33;:::i;:::-;9669:7;;-1:-1:-1;9728:3:1;9713:19;;9700:33;;9742;9700;9742;:::i;:::-;9794:7;;-1:-1:-1;9854:3:1;9839:19;;9826:33;;9871:16;;;9868:36;;;9900:1;9897;9890:12;9868:36;;9923:51;9966:7;9955:8;9944:9;9940:24;9923:51;:::i;:::-;9913:61;;;8872:1108;;;;;;;;;;:::o;9985:464::-;10069:6;10077;10085;10138:2;10126:9;10117:7;10113:23;10109:32;10106:52;;;10154:1;10151;10144:12;10106:52;10177:28;10195:9;10177:28;:::i;:::-;10167:38;;10256:2;10245:9;10241:18;10228:32;-1:-1:-1;;;;;10275:6:1;10272:30;10269:50;;;10315:1;10312;10305:12;10269:50;10338:49;10379:7;10370:6;10359:9;10355:22;10338:49;:::i;:::-;10328:59;;;10406:37;10439:2;10428:9;10424:18;10406:37;:::i;:::-;10396:47;;9985:464;;;;;:::o;10636:247::-;10695:6;10748:2;10736:9;10727:7;10723:23;10719:32;10716:52;;;10764:1;10761;10754:12;10716:52;10803:9;10790:23;10822:31;10847:5;10822:31;:::i;11111:256::-;11177:6;11185;11238:2;11226:9;11217:7;11213:23;11209:32;11206:52;;;11254:1;11251;11244:12;11206:52;11277:28;11295:9;11277:28;:::i;:::-;11267:38;;11324:37;11357:2;11346:9;11342:18;11324:37;:::i;:::-;11314:47;;11111:256;;;;;:::o;11372:320::-;11440:6;11493:2;11481:9;11472:7;11468:23;11464:32;11461:52;;;11509:1;11506;11499:12;11461:52;11549:9;11536:23;-1:-1:-1;;;;;11574:6:1;11571:30;11568:50;;;11614:1;11611;11604:12;11568:50;11637:49;11678:7;11669:6;11658:9;11654:22;11637:49;:::i;11697:315::-;11762:6;11770;11823:2;11811:9;11802:7;11798:23;11794:32;11791:52;;;11839:1;11836;11829:12;11791:52;11878:9;11865:23;11897:31;11922:5;11897:31;:::i;:::-;11947:5;-1:-1:-1;11971:35:1;12002:2;11987:18;;11971:35;:::i;12017:183::-;12077:4;-1:-1:-1;;;;;12102:6:1;12099:30;12096:56;;;12132:18;;:::i;:::-;-1:-1:-1;12177:1:1;12173:14;12189:4;12169:25;;12017:183::o;12205:662::-;12259:5;12312:3;12305:4;12297:6;12293:17;12289:27;12279:55;;12330:1;12327;12320:12;12279:55;12366:6;12353:20;12392:4;12416:60;12432:43;12472:2;12432:43;:::i;12416:60::-;12510:15;;;12596:1;12592:10;;;;12580:23;;12576:32;;;12541:12;;;;12620:15;;;12617:35;;;12648:1;12645;12638:12;12617:35;12684:2;12676:6;12672:15;12696:142;12712:6;12707:3;12704:15;12696:142;;;12778:17;;12766:30;;12816:12;;;;12729;;12696:142;;;-1:-1:-1;12856:5:1;12205:662;-1:-1:-1;;;;;;12205:662:1:o;12872:1199::-;13035:6;13043;13051;13059;13067;13075;13083;13136:3;13124:9;13115:7;13111:23;13107:33;13104:53;;;13153:1;13150;13143:12;13104:53;13192:9;13179:23;13211:31;13236:5;13211:31;:::i;:::-;13261:5;-1:-1:-1;13285:37:1;13318:2;13303:18;;13285:37;:::i;:::-;13275:47;;13373:2;13362:9;13358:18;13345:32;-1:-1:-1;;;;;13437:2:1;13429:6;13426:14;13423:34;;;13453:1;13450;13443:12;13423:34;13476:49;13517:7;13508:6;13497:9;13493:22;13476:49;:::i;:::-;13466:59;;13578:2;13567:9;13563:18;13550:32;13534:48;;13607:2;13597:8;13594:16;13591:36;;;13623:1;13620;13613:12;13591:36;13646:63;13701:7;13690:8;13679:9;13675:24;13646:63;:::i;:::-;13636:73;;13761:3;13750:9;13746:19;13733:33;13718:48;;13775:33;13800:7;13775:33;:::i;:::-;13827:7;13817:17;;13853:39;13887:3;13876:9;13872:19;13853:39;:::i;:::-;13843:49;;13945:3;13934:9;13930:19;13917:33;13901:49;;13975:2;13965:8;13962:16;13959:36;;;13991:1;13988;13981:12;14503:665;14598:6;14606;14614;14622;14675:3;14663:9;14654:7;14650:23;14646:33;14643:53;;;14692:1;14689;14682:12;14643:53;14731:9;14718:23;14750:31;14775:5;14750:31;:::i;:::-;14800:5;-1:-1:-1;14857:2:1;14842:18;;14829:32;14870:33;14829:32;14870:33;:::i;:::-;14922:7;-1:-1:-1;14976:2:1;14961:18;;14948:32;;-1:-1:-1;15031:2:1;15016:18;;15003:32;-1:-1:-1;;;;;15047:30:1;;15044:50;;;15090:1;15087;15080:12;15044:50;15113:49;15154:7;15145:6;15134:9;15130:22;15113:49;:::i;:::-;15103:59;;;14503:665;;;;;;;:::o;15173:622::-;15268:6;15276;15284;15292;15300;15353:3;15341:9;15332:7;15328:23;15324:33;15321:53;;;15370:1;15367;15360:12;15321:53;15393:28;15411:9;15393:28;:::i;:::-;15383:38;;15440:37;15473:2;15462:9;15458:18;15440:37;:::i;:::-;15430:47;;15524:2;15513:9;15509:18;15496:32;15486:42;;15579:2;15568:9;15564:18;15551:32;-1:-1:-1;;;;;15598:6:1;15595:30;15592:50;;;15638:1;15635;15628:12;15592:50;15677:58;15727:7;15718:6;15707:9;15703:22;15677:58;:::i;:::-;15173:622;;;;-1:-1:-1;15173:622:1;;-1:-1:-1;15754:8:1;;15651:84;15173:622;-1:-1:-1;;;15173:622:1:o;15800:460::-;15882:6;15890;15898;15951:2;15939:9;15930:7;15926:23;15922:32;15919:52;;;15967:1;15964;15957:12;15919:52;15990:28;16008:9;15990:28;:::i;:::-;15980:38;;16037:35;16068:2;16057:9;16053:18;16037:35;:::i;16265:324::-;16340:6;16348;16356;16409:2;16397:9;16388:7;16384:23;16380:32;16377:52;;;16425:1;16422;16415:12;16377:52;16448:28;16466:9;16448:28;:::i;:::-;16438:38;;16495:37;16528:2;16517:9;16513:18;16495:37;:::i;:::-;16485:47;;16579:2;16568:9;16564:18;16551:32;16541:42;;16265:324;;;;;:::o;16594:388::-;16662:6;16670;16723:2;16711:9;16702:7;16698:23;16694:32;16691:52;;;16739:1;16736;16729:12;16691:52;16778:9;16765:23;16797:31;16822:5;16797:31;:::i;:::-;16847:5;-1:-1:-1;16904:2:1;16889:18;;16876:32;16917:33;16876:32;16917:33;:::i;:::-;16969:7;16959:17;;;16594:388;;;;;:::o;16987:907::-;17121:6;17129;17137;17145;17153;17206:3;17194:9;17185:7;17181:23;17177:33;17174:53;;;17223:1;17220;17213:12;17174:53;17246:28;17264:9;17246:28;:::i;:::-;17236:38;;17325:2;17314:9;17310:18;17297:32;-1:-1:-1;;;;;17389:2:1;17381:6;17378:14;17375:34;;;17405:1;17402;17395:12;17375:34;17428:49;17469:7;17460:6;17449:9;17445:22;17428:49;:::i;:::-;17418:59;;17530:2;17519:9;17515:18;17502:32;17486:48;;17559:2;17549:8;17546:16;17543:36;;;17575:1;17572;17565:12;17543:36;17598:63;17653:7;17642:8;17631:9;17627:24;17598:63;:::i;:::-;17588:73;;17680:35;17711:2;17700:9;17696:18;17680:35;:::i;17899:460::-;17983:6;17991;17999;18007;18060:3;18048:9;18039:7;18035:23;18031:33;18028:53;;;18077:1;18074;18067:12;18028:53;18100:28;18118:9;18100:28;:::i;:::-;18090:38;;18147:37;18180:2;18169:9;18165:18;18147:37;:::i;:::-;18137:47;;18234:2;18223:9;18219:18;18206:32;18247:31;18272:5;18247:31;:::i;:::-;17899:460;;;;-1:-1:-1;18297:5:1;;18349:2;18334:18;18321:32;;-1:-1:-1;;17899:460:1:o;18723:380::-;18802:1;18798:12;;;;18845;;;18866:61;;18920:4;18912:6;18908:17;18898:27;;18866:61;18973:2;18965:6;18962:14;18942:18;18939:38;18936:161;;19019:10;19014:3;19010:20;19007:1;19000:31;19054:4;19051:1;19044:15;19082:4;19079:1;19072:15;18936:161;;18723:380;;;:::o;19108:271::-;19291:6;19283;19278:3;19265:33;19247:3;19317:16;;19342:13;;;19317:16;19108:271;-1:-1:-1;19108:271:1:o;21028:409::-;21230:2;21212:21;;;21269:2;21249:18;;;21242:30;21308:34;21303:2;21288:18;;21281:62;-1:-1:-1;;;21374:2:1;21359:18;;21352:43;21427:3;21412:19;;21028:409::o;21652:266::-;21740:6;21735:3;21728:19;21792:6;21785:5;21778:4;21773:3;21769:14;21756:43;-1:-1:-1;21844:1:1;21819:16;;;21837:4;21815:27;;;21808:38;;;;21900:2;21879:15;;;-1:-1:-1;;21875:29:1;21866:39;;;21862:50;;21652:266::o;21923:326::-;22118:6;22110;22106:19;22095:9;22088:38;22162:2;22157;22146:9;22142:18;22135:30;22069:4;22182:61;22239:2;22228:9;22224:18;22216:6;22208;22182:61;:::i;24066:441::-;24119:5;24172:3;24165:4;24157:6;24153:17;24149:27;24139:55;;24190:1;24187;24180:12;24139:55;24219:6;24213:13;24250:48;24266:31;24294:2;24266:31;:::i;24250:48::-;24323:2;24314:7;24307:19;24369:3;24362:4;24357:2;24349:6;24345:15;24341:26;24338:35;24335:55;;;24386:1;24383;24376:12;24335:55;24399:77;24473:2;24466:4;24457:7;24453:18;24446:4;24438:6;24434:17;24399:77;:::i;24512:1104::-;24625:6;24633;24686:2;24674:9;24665:7;24661:23;24657:32;24654:52;;;24702:1;24699;24692:12;24654:52;24735:9;24729:16;-1:-1:-1;;;;;24805:2:1;24797:6;24794:14;24791:34;;;24821:1;24818;24811:12;24791:34;24844:60;24896:7;24887:6;24876:9;24872:22;24844:60;:::i;:::-;24834:70;;24923:2;24913:12;;24971:2;24960:9;24956:18;24950:25;25000:2;24990:8;24987:16;24984:36;;;25016:1;25013;25006:12;24984:36;25039:24;;;-1:-1:-1;25094:4:1;25086:13;;25082:27;-1:-1:-1;25072:55:1;;25123:1;25120;25113:12;25072:55;25152:2;25146:9;25175:60;25191:43;25231:2;25191:43;:::i;25175:60::-;25269:15;;;25351:1;25347:10;;;;25339:19;;25335:28;;;25300:12;;;;25375:19;;;25372:39;;;25407:1;25404;25397:12;25372:39;25431:11;;;;25451:135;25467:6;25462:3;25459:15;25451:135;;;25533:10;;25521:23;;25484:12;;;;25564;;;;25451:135;;;25605:5;25595:15;;;;;;;24512:1104;;;;;:::o;27056:127::-;27117:10;27112:3;27108:20;27105:1;27098:31;27148:4;27145:1;27138:15;27172:4;27169:1;27162:15;27188:128;27255:9;;;27276:11;;;27273:37;;;27290:18;;:::i;27321:360::-;27532:6;27524;27519:3;27506:33;27602:2;27598:15;;;;-1:-1:-1;;27594:53:1;27558:16;;27583:65;;;27672:2;27664:11;;27321:360;-1:-1:-1;27321:360:1:o;27811:544::-;27912:2;27907:3;27904:11;27901:448;;;27948:1;27973:5;27969:2;27962:17;28018:4;28014:2;28004:19;28088:2;28076:10;28072:19;28069:1;28065:27;28059:4;28055:38;28124:4;28112:10;28109:20;28106:47;;;-1:-1:-1;28147:4:1;28106:47;28202:2;28197:3;28193:12;28190:1;28186:20;28180:4;28176:31;28166:41;;28257:82;28275:2;28268:5;28265:13;28257:82;;;28320:17;;;28301:1;28290:13;28257:82;;28531:1348;28655:3;28649:10;-1:-1:-1;;;;;28674:6:1;28671:30;28668:56;;;28704:18;;:::i;:::-;28733:96;28822:6;28782:38;28814:4;28808:11;28782:38;:::i;:::-;28776:4;28733:96;:::i;:::-;28884:4;;28948:2;28937:14;;28965:1;28960:662;;;;29666:1;29683:6;29680:89;;;-1:-1:-1;29735:19:1;;;29729:26;29680:89;-1:-1:-1;;28488:1:1;28484:11;;;28480:24;28476:29;28466:40;28512:1;28508:11;;;28463:57;29782:81;;28930:943;;28960:662;27758:1;27751:14;;;27795:4;27782:18;;-1:-1:-1;;28996:20:1;;;29113:236;29127:7;29124:1;29121:14;29113:236;;;29216:19;;;29210:26;29195:42;;29308:27;;;;29276:1;29264:14;;;;29143:19;;29113:236;;;29117:3;29377:6;29368:7;29365:19;29362:201;;;29438:19;;;29432:26;-1:-1:-1;;29521:1:1;29517:14;;;29533:3;29513:24;29509:37;29505:42;29490:58;29475:74;;29362:201;-1:-1:-1;;;;;29609:1:1;29593:14;;;29589:22;29576:36;;-1:-1:-1;28531:1348:1:o;29884:496::-;30063:3;30101:6;30095:13;30117:66;30176:6;30171:3;30164:4;30156:6;30152:17;30117:66;:::i;:::-;30246:13;;30205:16;;;;30268:70;30246:13;30205:16;30315:4;30303:17;;30268:70;:::i;:::-;30354:20;;29884:496;-1:-1:-1;;;;29884:496:1:o;30385:498::-;30585:4;30614:6;30659:2;30651:6;30647:15;30636:9;30629:34;30711:2;30703:6;30699:15;30694:2;30683:9;30679:18;30672:43;;30751:6;30746:2;30735:9;30731:18;30724:34;30794:3;30789:2;30778:9;30774:18;30767:31;30815:62;30872:3;30861:9;30857:19;30849:6;30841;30815:62;:::i;:::-;30807:70;30385:498;-1:-1:-1;;;;;;;30385:498:1:o;32098:493::-;32347:6;32339;32335:19;32324:9;32317:38;32391:3;32386:2;32375:9;32371:18;32364:31;32298:4;32412:62;32469:3;32458:9;32454:19;32446:6;32438;32412:62;:::i;:::-;-1:-1:-1;;;;;32510:31:1;;;;32505:2;32490:18;;32483:59;-1:-1:-1;32573:2:1;32558:18;32551:34;32404:70;32098:493;-1:-1:-1;;;32098:493:1:o;32596:650::-;32885:6;32873:19;;32855:38;;-1:-1:-1;;;;;32929:32:1;;32924:2;32909:18;;32902:60;32949:3;32993:2;32978:18;;32971:31;;;-1:-1:-1;;33025:46:1;;33051:19;;33043:6;33025:46;:::i;:::-;33121:6;33114:14;33107:22;33102:2;33091:9;33087:18;33080:50;33179:9;33171:6;33167:22;33161:3;33150:9;33146:19;33139:51;33207:33;33233:6;33225;33207:33;:::i;:::-;33199:41;32596:650;-1:-1:-1;;;;;;;;32596:650:1:o;33251:245::-;33330:6;33338;33391:2;33379:9;33370:7;33366:23;33362:32;33359:52;;;33407:1;33404;33397:12;33359:52;-1:-1:-1;;33430:16:1;;33486:2;33471:18;;;33465:25;33430:16;;33465:25;;-1:-1:-1;33251:245:1:o;34214:1202::-;-1:-1:-1;;;;;34331:3:1;34328:27;34325:53;;;34358:18;;:::i;:::-;34387:93;34476:3;34436:38;34468:4;34462:11;34436:38;:::i;:::-;34430:4;34387:93;:::i;:::-;34506:1;34531:2;34526:3;34523:11;34548:1;34543:615;;;;35202:1;35219:3;35216:93;;;-1:-1:-1;35275:19:1;;;35262:33;35216:93;-1:-1:-1;;28488:1:1;28484:11;;;28480:24;28476:29;28466:40;28512:1;28508:11;;;28463:57;35322:78;;34516:894;;34543:615;27758:1;27751:14;;;27795:4;27782:18;;-1:-1:-1;;34579:17:1;;;34679:9;34701:229;34715:7;34712:1;34709:14;34701:229;;;34804:19;;;34791:33;34776:49;;34911:4;34896:20;;;;34864:1;34852:14;;;;34731:12;34701:229;;;34705:3;34958;34949:7;34946:16;34943:159;;;35082:1;35078:6;35072:3;35066;35063:1;35059:11;35055:21;35051:34;35047:39;35034:9;35029:3;35025:19;35012:33;35008:79;35000:6;34993:95;34943:159;;;35145:1;35139:3;35136:1;35132:11;35128:19;35122:4;35115:33;34516:894;;34214:1202;;;:::o;35421:435::-;35474:3;35512:5;35506:12;35539:6;35534:3;35527:19;35565:4;35594:2;35589:3;35585:12;35578:19;;35631:2;35624:5;35620:14;35652:1;35662:169;35676:6;35673:1;35670:13;35662:169;;;35737:13;;35725:26;;35771:12;;;;35806:15;;;;35698:1;35691:9;35662:169;;;-1:-1:-1;35847:3:1;;35421:435;-1:-1:-1;;;;;35421:435:1:o;35861:422::-;36086:2;36075:9;36068:21;36049:4;36112:45;36153:2;36142:9;36138:18;36130:6;36112:45;:::i;:::-;36205:9;36197:6;36193:22;36188:2;36177:9;36173:18;36166:50;36233:44;36270:6;36262;36233:44;:::i;:::-;36225:52;35861:422;-1:-1:-1;;;;;35861:422:1:o;37803:335::-;37882:6;37935:2;37923:9;37914:7;37910:23;37906:32;37903:52;;;37951:1;37948;37941:12;37903:52;37984:9;37978:16;-1:-1:-1;;;;;38009:6:1;38006:30;38003:50;;;38049:1;38046;38039:12;38003:50;38072:60;38124:7;38115:6;38104:9;38100:22;38072:60;:::i;38143:557::-;38400:6;38392;38388:19;38377:9;38370:38;38444:3;38439:2;38428:9;38424:18;38417:31;38351:4;38471:46;38512:3;38501:9;38497:19;38489:6;38471:46;:::i;:::-;-1:-1:-1;;;;;38557:6:1;38553:31;38548:2;38537:9;38533:18;38526:59;38633:9;38625:6;38621:22;38616:2;38605:9;38601:18;38594:50;38661:33;38687:6;38679;38661:33;:::i;39755:135::-;39794:3;39815:17;;;39812:43;;39835:18;;:::i;:::-;-1:-1:-1;39882:1:1;39871:13;;39755:135::o;40174:401::-;40376:2;40358:21;;;40415:2;40395:18;;;40388:30;40454:34;40449:2;40434:18;;40427:62;-1:-1:-1;;;40520:2:1;40505:18;;40498:35;40565:3;40550:19;;40174:401::o;40985:127::-;41046:10;41041:3;41037:20;41034:1;41027:31;41077:4;41074:1;41067:15;41101:4;41098:1;41091:15;41117:125;41182:9;;;41203:10;;;41200:36;;;41216:18;;:::i;42375:840::-;42724:6;42716;42712:19;42701:9;42694:38;42768:3;42763:2;42752:9;42748:18;42741:31;42675:4;42795:46;42836:3;42825:9;42821:19;42813:6;42795:46;:::i;:::-;42889:9;42881:6;42877:22;42872:2;42861:9;42857:18;42850:50;42923:33;42949:6;42941;42923:33;:::i;:::-;-1:-1:-1;;;;;43030:15:1;;;43025:2;43010:18;;43003:43;43083:15;;43077:3;43062:19;;43055:44;43136:22;;;42983:3;43115:19;;43108:51;42909:47;-1:-1:-1;43176:33:1;42909:47;43194:6;43176:33;:::i;:::-;43168:41;42375:840;-1:-1:-1;;;;;;;;;42375:840:1:o;43971:168::-;44044:9;;;44075;;44092:15;;;44086:22;;44072:37;44062:71;;44113:18;;:::i;44144:287::-;44273:3;44311:6;44305:13;44327:66;44386:6;44381:3;44374:4;44366:6;44362:17;44327:66;:::i;:::-;44409:16;;;;;44144:287;-1:-1:-1;;44144:287:1:o;44436:261::-;44615:2;44604:9;44597:21;44578:4;44635:56;44687:2;44676:9;44672:18;44664:6;44635:56;:::i;44702:289::-;44877:6;44866:9;44859:25;44920:2;44915;44904:9;44900:18;44893:30;44840:4;44940:45;44981:2;44970:9;44966:18;44958:6;44940:45;:::i;46399:414::-;46601:2;46583:21;;;46640:2;46620:18;;;46613:30;46679:34;46674:2;46659:18;;46652:62;-1:-1:-1;;;46745:2:1;46730:18;;46723:48;46803:3;46788:19;;46399:414::o;46950:719::-;47253:6;47245;47241:19;47230:9;47223:38;47297:3;47292:2;47281:9;47277:18;47270:31;47204:4;47324:46;47365:3;47354:9;47350:19;47342:6;47324:46;:::i;:::-;-1:-1:-1;;;;;47410:6:1;47406:31;47401:2;47390:9;47386:18;47379:59;47486:9;47478:6;47474:22;47469:2;47458:9;47454:18;47447:50;47520:33;47546:6;47538;47520:33;:::i;:::-;47506:47;;47602:9;47594:6;47590:22;47584:3;47573:9;47569:19;47562:51;47630:33;47656:6;47648;47630:33;:::i;49210:489::-;-1:-1:-1;;;;;49479:15:1;;;49461:34;;49531:15;;49526:2;49511:18;;49504:43;49578:2;49563:18;;49556:34;;;49626:3;49621:2;49606:18;;49599:31;;;49404:4;;49647:46;;49673:19;;49665:6;49647:46;:::i;:::-;49639:54;49210:489;-1:-1:-1;;;;;;49210:489:1:o;49704:249::-;49773:6;49826:2;49814:9;49805:7;49801:23;49797:32;49794:52;;;49842:1;49839;49832:12;49794:52;49874:9;49868:16;49893:30;49917:5;49893:30;:::i
Swarm Source
ipfs://0596b71c81cbed2675e7f1a3817ac347dca4a3f53049c443329729b4e3c197f5
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$136.44
Net Worth in ETH
Token Allocations
ETH
53.32%
BNB
46.57%
POL
0.10%
Multichain Portfolio | 35 Chains
Loading...
Loading
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.