ERC-721
Source Code
Overview
Max Total Supply
13,042 DLGATE
Holders
8,358
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 DLGATELoading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
Dappgate
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/**
*Submitted for verification at Nova.Arbiscan.io on 2023-12-28
*/
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Q&Rdq6qKDWQ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@QRXt<~'` ._^cag@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@k*, `!jQ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@U; ,}Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@g; 'w@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@i ~Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@L '*Ij}i~ :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@k 7@@@@@@@D =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@! k@@@@@@@@ `Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; k@@@@@@@@ `Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; k@@@@@@@@ `Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@t^^^^^^^^^^^^;~'` k@@@@@@@@ `Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@QUz+:'` k@@@@@@@@ '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@K?' k@@@@@@@@ X@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@b; k@@@@@@@@ f@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Q; k@@@@@@@@ =Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Q' k@@@@@@@@ `;5Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7 k@@@@@@@@ ,~|ZQ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; k@@@@@@@@ `',;><<<<<<<<<<<?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; k@@@@@@@@ `Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; k@@@@@@@@ `Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@! k@@@@@@@@ `Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@f y@@@@@@@Q ~@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; +obDdhL` `Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@? :Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a' `L@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@k; ,YQ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@QP>' `;}Q@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Rj7^,` `';iZWQ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Q#RdqAAKDWQ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
/**
* @dev Interface of the ONFT Core standard
*/
interface IONFT721Core is IERC165 {
/**
* @dev Emitted when `_tokenIds[]` are moved from the `_sender` to (`_dstChainId`, `_toAddress`)
* `_nonce` is the outbound nonce from
*/
event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes indexed _toAddress, uint[] _tokenIds);
event ReceiveFromChain(uint16 indexed _srcChainId, bytes indexed _srcAddress, address indexed _toAddress, uint[] _tokenIds);
event SetMinGasToTransferAndStore(uint256 _minGasToTransferAndStore);
event SetDstChainIdToTransferGas(uint16 _dstChainId, uint256 _dstChainIdToTransferGas);
event SetDstChainIdToBatchLimit(uint16 _dstChainId, uint256 _dstChainIdToBatchLimit);
/**
* @dev Emitted when `_payload` was received from lz, but not enough gas to deliver all tokenIds
*/
event CreditStored(bytes32 _hashedPayload, bytes _payload);
/**
* @dev Emitted when `_hashedPayload` has been completely delivered
*/
event CreditCleared(bytes32 _hashedPayload);
/**
* @dev send token `_tokenId` to (`_dstChainId`, `_toAddress`) from `_from`
* `_toAddress` can be any size depending on the `dstChainId`.
* `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
* `_adapterParams` is a flexible bytes array to indicate messaging adapter services
*/
function sendFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
/**
* @dev send tokens `_tokenIds[]` to (`_dstChainId`, `_toAddress`) from `_from`
* `_toAddress` can be any size depending on the `dstChainId`.
* `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
* `_adapterParams` is a flexible bytes array to indicate messaging adapter services
*/
function sendBatchFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
/**
* @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
* _dstChainId - L0 defined chain id to send tokens too
* _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
* _tokenId - token Id to transfer
* _useZro - indicates to use zro to pay L0 fees
* _adapterParams - flexible bytes array to indicate messaging adapter services in L0
*/
function estimateSendFee(uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
/**
* @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
* _dstChainId - L0 defined chain id to send tokens too
* _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
* _tokenIds[] - token Ids to transfer
* _useZro - indicates to use zro to pay L0 fees
* _adapterParams - flexible bytes array to indicate messaging adapter services in L0
*/
function estimateSendBatchFee(uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
}
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
/**
* @dev Interface of the ONFT standard
*/
interface IONFT721 is IONFT721Core, IERC721 {
}
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
interface ILayerZeroReceiver {
// @notice LayerZero endpoint will invoke this function to deliver the message on the destination
// @param _srcChainId - the source endpoint identifier
// @param _srcAddress - the source sending contract address from the source chain
// @param _nonce - the ordered message nonce
// @param _payload - the signed payload is the UA bytes has encoded to be sent
function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;
}
interface ILayerZeroUserApplicationConfig {
// @notice set the configuration of the LayerZero messaging library of the specified version
// @param _version - messaging library version
// @param _chainId - the chainId for the pending config change
// @param _configType - type of configuration. every messaging library has its own convention.
// @param _config - configuration in the bytes. can encode arbitrary content.
function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;
// @notice set the send() LayerZero messaging library version to _version
// @param _version - new messaging library version
function setSendVersion(uint16 _version) external;
// @notice set the lzReceive() LayerZero messaging library version to _version
// @param _version - new messaging library version
function setReceiveVersion(uint16 _version) external;
// @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload
// @param _srcChainId - the chainId of the source chain
// @param _srcAddress - the contract address of the source contract at the source chain
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}
interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
// @notice send a LayerZero message to the specified address at a LayerZero endpoint.
// @param _dstChainId - the destination chain identifier
// @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
// @param _payload - a custom bytes payload to send to the destination contract
// @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
// @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
// @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
// @notice used by the messaging library to publish verified payload
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source contract (as bytes) at the source chain
// @param _dstAddress - the address on destination chain
// @param _nonce - the unbound message ordering nonce
// @param _gasLimit - the gas limit for external contract execution
// @param _payload - verified payload to send to the destination contract
function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external;
// @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);
// @notice get the outboundNonce from this source chain which, consequently, is always an EVM
// @param _srcAddress - the source chain contract address
function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);
// @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery
// @param _dstChainId - the destination chain identifier
// @param _userApplication - the user app address on this EVM chain
// @param _payload - the custom message to send over LayerZero
// @param _payInZRO - if false, user app pays the protocol fee in native token
// @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain
function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee);
// @notice get this Endpoint's immutable source identifier
function getChainId() external view returns (uint16);
// @notice the interface to retry failed message on this Endpoint destination
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
// @param _payload - the payload to be retried
function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;
// @notice query if any STORED payload (message blocking) at the endpoint.
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);
// @notice query if the _libraryAddress is valid for sending msgs.
// @param _userApplication - the user app address on this EVM chain
function getSendLibraryAddress(address _userApplication) external view returns (address);
// @notice query if the _libraryAddress is valid for receiving msgs.
// @param _userApplication - the user app address on this EVM chain
function getReceiveLibraryAddress(address _userApplication) external view returns (address);
// @notice query if the non-reentrancy guard for send() is on
// @return true if the guard is on. false otherwise
function isSendingPayload() external view returns (bool);
// @notice query if the non-reentrancy guard for receive() is on
// @return true if the guard is on. false otherwise
function isReceivingPayload() external view returns (bool);
// @notice get the configuration of the LayerZero messaging library of the specified version
// @param _version - messaging library version
// @param _chainId - the chainId for the pending config change
// @param _userApplication - the contract address of the user application
// @param _configType - type of configuration. every messaging library has its own convention.
function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory);
// @notice get the send() LayerZero messaging library version
// @param _userApplication - the contract address of the user application
function getSendVersion(address _userApplication) external view returns (uint16);
// @notice get the lzReceive() LayerZero messaging library version
// @param _userApplication - the contract address of the user application
function getReceiveVersion(address _userApplication) external view returns (uint16);
}
/*
* @title Solidity Bytes Arrays Utils
* @author Gonçalo Sá <[email protected]>
*
* @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
* The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
*/
library BytesLib {
function concat(
bytes memory _preBytes,
bytes memory _postBytes
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
assembly {
// Read the first 32 bytes of _preBytes storage, which is the length
// of the array. (We don't need to use the offset into the slot
// because arrays use the entire slot.)
let fslot := sload(_preBytes.slot)
// Arrays of 31 bytes or less have an even value in their slot,
// while longer arrays have an odd value. The actual length is
// the slot divided by two for odd values, and the lowest order
// byte divided by two for even values.
// If the slot is even, bitwise and the slot with 255 and divide by
// two to get the length. If the slot is odd, bitwise and the slot
// with -1 and divide by two.
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
let newlength := add(slength, mlength)
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
switch add(lt(slength, 32), lt(newlength, 32))
case 2 {
// Since the new array still fits in the slot, we just need to
// update the contents of the slot.
// uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
sstore(
_preBytes.slot,
// all the modifications to the slot are inside this
// next block
add(
// we can just add to the slot contents because the
// bytes we want to change are the LSBs
fslot,
add(
mul(
div(
// load the bytes from memory
mload(add(_postBytes, 0x20)),
// zero all bytes to the right
exp(0x100, sub(32, mlength))
),
// and now shift left the number of bytes to
// leave space for the length in the slot
exp(0x100, sub(32, newlength))
),
// increase length by the double of the memory
// bytes length
mul(mlength, 2)
)
)
)
}
case 1 {
// The stored value fits in the slot, but the combined value
// will exceed it.
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// The contents of the _postBytes array start 32 bytes into
// the structure. Our first read should obtain the `submod`
// bytes that can fit into the unused space in the last word
// of the stored array. To get this, we read 32 bytes starting
// from `submod`, so the data we read overlaps with the array
// contents by `submod` bytes. Masking the lowest-order
// `submod` bytes allows us to add that value directly to the
// stored value.
let submod := sub(32, slength)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(
sc,
add(
and(
fslot,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
),
and(mload(mc), mask)
)
)
for {
mc := add(mc, 0x20)
sc := add(sc, 1)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
default {
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
// Start copying to the last used word of the stored array.
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// Copy over the first `submod` bytes of the new data as in
// case 1 above.
let slengthmod := mod(slength, 32)
let mlengthmod := mod(mlength, 32)
let submod := sub(32, slengthmod)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(sc, add(sload(sc), and(mload(mc), mask)))
for {
sc := add(sc, 1)
mc := add(mc, 0x20)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
}
}
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
)
internal
pure
returns (bytes memory)
{
require(_length + 31 >= _length, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
//zero out the 32 bytes slice we are about to return
//we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
uint16 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x2), _start))
}
return tempUint;
}
function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
uint32 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x4), _start))
}
return tempUint;
}
function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
uint64 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x8), _start))
}
return tempUint;
}
function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
uint96 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xc), _start))
}
return tempUint;
}
function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
uint128 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x10), _start))
}
return tempUint;
}
function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
uint256 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
bytes32 tempBytes32;
assembly {
tempBytes32 := mload(add(add(_bytes, 0x20), _start))
}
return tempBytes32;
}
function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
bool success = true;
assembly {
let length := mload(_preBytes)
// if lengths don't match the arrays are not equal
switch eq(length, mload(_postBytes))
case 1 {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
let mc := add(_preBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
} eq(add(lt(mc, end), cb), 2) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// if any of these checks fails then arrays are not equal
if iszero(eq(mload(mc), mload(cc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
function equalStorage(
bytes storage _preBytes,
bytes memory _postBytes
)
internal
view
returns (bool)
{
bool success = true;
assembly {
// we know _preBytes_offset is 0
let fslot := sload(_preBytes.slot)
// Decode the length of the stored array like in concatStorage().
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
// if lengths don't match the arrays are not equal
switch eq(slength, mlength)
case 1 {
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
if iszero(iszero(slength)) {
switch lt(slength, 32)
case 1 {
// blank the last byte which is the length
fslot := mul(div(fslot, 0x100), 0x100)
if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
// unsuccess:
success := 0
}
}
default {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := keccak256(0x0, 0x20)
let mc := add(_postBytes, 0x20)
let end := add(mc, mlength)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
for {} eq(add(lt(mc, end), cb), 2) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
if iszero(eq(sload(sc), mload(mc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
}
/*
* a generic LzReceiver implementation
*/
abstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
using BytesLib for bytes;
// ua can not send payload larger than this by default, but it can be changed by the ua owner
uint constant public DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;
ILayerZeroEndpoint public immutable lzEndpoint;
mapping(uint16 => bytes) public trustedRemoteLookup;
mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;
mapping(uint16 => uint) public payloadSizeLimitLookup;
address public precrime;
event SetPrecrime(address precrime);
event SetTrustedRemote(uint16 _remoteChainId, bytes _path);
event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);
event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);
constructor(address _endpoint) {
lzEndpoint = ILayerZeroEndpoint(_endpoint);
}
function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual override {
// lzReceive must be called by the endpoint for security
require(_msgSender() == address(lzEndpoint), "LzApp: invalid endpoint caller");
bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];
// if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.
require(_srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote), "LzApp: invalid source sending contract");
_blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
}
// abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging
function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;
function _lzSend(uint16 _dstChainId, bytes memory _payload, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, uint _nativeFee) internal virtual {
bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];
require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
_checkPayloadSize(_dstChainId, _payload.length);
lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);
}
function _checkGasLimit(uint16 _dstChainId, uint16 _type, bytes memory _adapterParams, uint _extraGas) internal view virtual {
uint providedGasLimit = _getGasLimit(_adapterParams);
uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;
require(minGasLimit > 0, "LzApp: minGasLimit not set");
require(providedGasLimit >= minGasLimit, "LzApp: gas limit is too low");
}
function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {
require(_adapterParams.length >= 34, "LzApp: invalid adapterParams");
assembly {
gasLimit := mload(add(_adapterParams, 34))
}
}
function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {
uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];
if (payloadSizeLimit == 0) { // use default if not set
payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;
}
require(_payloadSize <= payloadSizeLimit, "LzApp: payload size is too large");
}
//---------------------------UserApplication config----------------------------------------
function getConfig(uint16 _version, uint16 _chainId, address, uint _configType) external view returns (bytes memory) {
return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);
}
// generic config for LayerZero user Application
function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external override onlyOwner {
lzEndpoint.setConfig(_version, _chainId, _configType, _config);
}
function setSendVersion(uint16 _version) external override onlyOwner {
lzEndpoint.setSendVersion(_version);
}
function setReceiveVersion(uint16 _version) external override onlyOwner {
lzEndpoint.setReceiveVersion(_version);
}
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
}
// _path = abi.encodePacked(remoteAddress, localAddress)
// this function set the trusted path for the cross-chain communication
function setTrustedRemote(uint16 _remoteChainId, bytes calldata _path) external onlyOwner {
trustedRemoteLookup[_remoteChainId] = _path;
emit SetTrustedRemote(_remoteChainId, _path);
}
function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {
trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));
emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);
}
function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {
bytes memory path = trustedRemoteLookup[_remoteChainId];
require(path.length != 0, "LzApp: no trusted path record");
return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)
}
function setPrecrime(address _precrime) external onlyOwner {
precrime = _precrime;
emit SetPrecrime(_precrime);
}
function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner {
require(_minGas > 0, "LzApp: invalid minGas");
minDstGasLookup[_dstChainId][_packetType] = _minGas;
emit SetMinDstGas(_dstChainId, _packetType, _minGas);
}
// if the size is 0, it means default size limit
function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {
payloadSizeLimitLookup[_dstChainId] = _size;
}
//--------------------------- VIEW FUNCTION ----------------------------------------
function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {
bytes memory trustedSource = trustedRemoteLookup[_srcChainId];
return keccak256(trustedSource) == keccak256(_srcAddress);
}
}
library ExcessivelySafeCall {
uint256 constant LOW_28_MASK =
0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
/// @notice Use when you _really_ really _really_ don't trust the called
/// contract. This prevents the called contract from causing reversion of
/// the caller in as many ways as we can.
/// @dev The main difference between this and a solidity low-level call is
/// that we limit the number of bytes that the callee can cause to be
/// copied to caller memory. This prevents stupid things like malicious
/// contracts returning 10,000,000 bytes causing a local OOG when copying
/// to memory.
/// @param _target The address to call
/// @param _gas The amount of gas to forward to the remote contract
/// @param _maxCopy The maximum number of bytes of returndata to copy
/// to memory.
/// @param _calldata The data to send to the remote contract
/// @return success and returndata, as `.call()`. Returndata is capped to
/// `_maxCopy` bytes.
function excessivelySafeCall(
address _target,
uint256 _gas,
uint16 _maxCopy,
bytes memory _calldata
) internal returns (bool, bytes memory) {
// set up for assembly call
uint256 _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
// dispatch message to recipient
// by assembly calling "handle" function
// we call via assembly to avoid memcopying a very large returndata
// returned by a malicious contract
assembly {
_success := call(
_gas, // gas
_target, // recipient
0, // ether value
add(_calldata, 0x20), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
)
// limit our copy to 256 bytes
_toCopy := returndatasize()
if gt(_toCopy, _maxCopy) {
_toCopy := _maxCopy
}
// Store the length of the copied bytes
mstore(_returnData, _toCopy)
// copy the bytes from returndata[0:_toCopy]
returndatacopy(add(_returnData, 0x20), 0, _toCopy)
}
return (_success, _returnData);
}
/// @notice Use when you _really_ really _really_ don't trust the called
/// contract. This prevents the called contract from causing reversion of
/// the caller in as many ways as we can.
/// @dev The main difference between this and a solidity low-level call is
/// that we limit the number of bytes that the callee can cause to be
/// copied to caller memory. This prevents stupid things like malicious
/// contracts returning 10,000,000 bytes causing a local OOG when copying
/// to memory.
/// @param _target The address to call
/// @param _gas The amount of gas to forward to the remote contract
/// @param _maxCopy The maximum number of bytes of returndata to copy
/// to memory.
/// @param _calldata The data to send to the remote contract
/// @return success and returndata, as `.call()`. Returndata is capped to
/// `_maxCopy` bytes.
function excessivelySafeStaticCall(
address _target,
uint256 _gas,
uint16 _maxCopy,
bytes memory _calldata
) internal view returns (bool, bytes memory) {
// set up for assembly call
uint256 _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
// dispatch message to recipient
// by assembly calling "handle" function
// we call via assembly to avoid memcopying a very large returndata
// returned by a malicious contract
assembly {
_success := staticcall(
_gas, // gas
_target, // recipient
add(_calldata, 0x20), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
)
// limit our copy to 256 bytes
_toCopy := returndatasize()
if gt(_toCopy, _maxCopy) {
_toCopy := _maxCopy
}
// Store the length of the copied bytes
mstore(_returnData, _toCopy)
// copy the bytes from returndata[0:_toCopy]
returndatacopy(add(_returnData, 0x20), 0, _toCopy)
}
return (_success, _returnData);
}
/**
* @notice Swaps function selectors in encoded contract calls
* @dev Allows reuse of encoded calldata for functions with identical
* argument types but different names. It simply swaps out the first 4 bytes
* for the new selector. This function modifies memory in place, and should
* only be used with caution.
* @param _newSelector The new 4-byte selector
* @param _buf The encoded contract args
*/
function swapSelector(bytes4 _newSelector, bytes memory _buf)
internal
pure
{
require(_buf.length >= 4);
uint256 _mask = LOW_28_MASK;
assembly {
// load the first word of
let _word := mload(add(_buf, 0x20))
// mask out the top 4 bytes
// /x
_word := and(_word, _mask)
_word := or(_newSelector, _word)
mstore(add(_buf, 0x20), _word)
}
}
}
/*
* the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel
* this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking
* NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)
*/
abstract contract NonblockingLzApp is LzApp {
using ExcessivelySafeCall for address;
constructor(address _endpoint) LzApp(_endpoint) {}
mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;
event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);
event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);
// overriding the virtual function in LzReceiver
function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual override {
(bool success, bytes memory reason) = address(this).excessivelySafeCall(gasleft(), 150, abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload));
// try-catch all errors/exceptions
if (!success) {
_storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);
}
}
function _storeFailedMessage(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload, bytes memory _reason) internal virtual {
failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);
emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);
}
function nonblockingLzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual {
// only internal transaction
require(_msgSender() == address(this), "NonblockingLzApp: caller must be LzApp");
_nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
}
//@notice override this function
function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;
function retryMessage(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public payable virtual {
// assert there is message to retry
bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];
require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message");
require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload");
// clear the stored message
failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);
// execute the message. revert if it fails again
_nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);
}
}
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
abstract contract ONFT721Core is NonblockingLzApp, ERC165, ReentrancyGuard, IONFT721Core {
uint16 public constant FUNCTION_TYPE_SEND = 1;
struct StoredCredit {
uint16 srcChainId;
address toAddress;
uint256 index; // which index of the tokenIds remain
bool creditsRemain;
}
uint256 public minGasToTransferAndStore; // min amount of gas required to transfer, and also store the payload
mapping(uint16 => uint256) public dstChainIdToBatchLimit;
mapping(uint16 => uint256) public dstChainIdToTransferGas; // per transfer amount of gas required to mint/transfer on the dst
mapping(bytes32 => StoredCredit) public storedCredits;
constructor(uint256 _minGasToTransferAndStore, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
require(_minGasToTransferAndStore > 0, "minGasToTransferAndStore must be > 0");
minGasToTransferAndStore = _minGasToTransferAndStore;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IONFT721Core).interfaceId || super.supportsInterface(interfaceId);
}
function estimateSendFee(uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, bool _useZro, bytes memory _adapterParams) public view virtual override returns (uint nativeFee, uint zroFee) {
return estimateSendBatchFee(_dstChainId, _toAddress, _toSingletonArray(_tokenId), _useZro, _adapterParams);
}
function estimateSendFee2(uint16 _dstChainId, bytes memory payload, bool _useZro, bytes memory _adapterParams) public view virtual returns (uint nativeFee, uint zroFee) {
return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _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);
(uint nativeFee,) = estimateSendFee2(_dstChainId, payload, false, _adapterParams);
require(msg.value >= nativeFee, "Not enough gas to send");
_checkGasLimit(_dstChainId, FUNCTION_TYPE_SEND, _adapterParams, dstChainIdToTransferGas[_dstChainId] * _tokenIds.length);
_lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams, nativeFee);
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;
}
}
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/**
* @dev An `owner`'s token query was out of bounds for `index`.
*
* NOTE: The owner being `address(0)` indicates a global out of bounds index.
*/
error ERC721OutOfBoundsIndex(address owner, uint256 index);
/**
* @dev Batch mint is not allowed.
*/
error ERC721EnumerableForbiddenBatchMint();
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) {
if (index >= balanceOf(owner)) {
revert ERC721OutOfBoundsIndex(owner, index);
}
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual returns (uint256) {
if (index >= totalSupply()) {
revert ERC721OutOfBoundsIndex(address(0), index);
}
return _allTokens[index];
}
/**
* @dev See {ERC721-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual override {
super._beforeTokenTransfer(from, to, firstTokenId, batchSize);
if (batchSize > 1) {
// Will only trigger during construction. Batch transferring (minting) is not available afterwards.
revert ERC721EnumerableForbiddenBatchMint();
}
uint256 tokenId = firstTokenId;
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
/**
* @dev Private function to add a token to this extension's ownership-tracking data structures.
* @param to address representing the new owner of the given token ID
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
/**
* @dev Private function to add a token to this extension's token tracking data structures.
* @param tokenId uint256 ID of the token to be added to the tokens list
*/
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
/**
* @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
* while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
* gas optimizations e.g. when performing a transfer operation (avoiding double writes).
* This has O(1) time complexity, but alters the order of the _ownedTokens array.
* @param from address representing the previous owner of the given token ID
* @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
// To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
// This also deletes the contents at the last position of the array
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
/**
* @dev Private function to remove a token from this extension's token tracking data structures.
* This has O(1) time complexity, but alters the order of the _allTokens array.
* @param tokenId uint256 ID of the token to be removed from the tokens list
*/
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
// To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
// then delete the last slot (swap and pop).
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
// When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
// rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
// an 'if' statement (like in _removeTokenFromOwnerEnumeration)
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
// This also deletes the contents at the last position of the array
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
// NOTE: this ONFT contract has no public minting logic.
// must implement your own minting logic in child classes
contract ONFT721 is ONFT721Core, ERC721Enumerable, 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, ERC721Enumerable, 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);
}
}
}
contract Dappgate is ONFT721 {
using Strings for uint256;
uint public mintFee = 0.00033 ether;
uint public bridgeFee = 0.00006 ether;
uint public nextMintId;
uint public maxMintId;
string public baseTokenURI;
string public baseExtension = "";
address public moderatorAddress;
/// @notice Constructor for the UniversalONFT
/// @param _layerZeroEndpoint handles message transmission across chains
/// @param _startMintId the starting mint number on this chain
/// @param _endMintId the max number of mints on this chain
constructor(
uint256 _minGasToTransfer,
address _layerZeroEndpoint,
uint _startMintId,
uint _endMintId) ONFT721("DappGate by DappLabs", "DLGATE", _minGasToTransfer, _layerZeroEndpoint) {
nextMintId = _startMintId;
maxMintId = _endMintId;
baseTokenURI = "https://gas.zkl.app/";
moderatorAddress = 0x3772f434d796A1B974E9B2cD37055a075F3450be;
}
function mint() public payable {
require(msg.value >= mintFee, "Not enough ether sent");
require(nextMintId <= maxMintId, "Max mint reached");
(bool success, ) = payable(moderatorAddress).call{
value: msg.value
}("");
require(success);
uint newId = nextMintId;
nextMintId++;
_safeMint(msg.sender, newId);
}
function batchMint(uint256 amount) external payable {
require(amount > 0, "Cannot mint 0 amount.");
require(msg.value >= mintFee * amount, "Not enough ether sent");
require(nextMintId + amount <= maxMintId, "Max mint reached");
(bool success, ) = payable(moderatorAddress).call{
value: msg.value
}("");
require(success);
for (uint64 i = 0; i < amount; i++) {
uint newId = nextMintId;
nextMintId++;
_safeMint(msg.sender, newId);
}
}
function sendFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable virtual override(ONFT721Core, IONFT721Core) {
require(bridgeFee <= msg.value, "Not enough ether");
(bool success, ) = payable(moderatorAddress).call{
value: bridgeFee
}("");
require(success);
_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(ONFT721Core, IONFT721Core) {
require(bridgeFee <= msg.value, "Not enough ether");
(bool success, ) = payable(moderatorAddress).call{
value: bridgeFee
}("");
require(success);
_send(_from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams);
}
function batchBridge(address _from, uint16[] memory _dstChainIds, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable {
require(_dstChainIds.length == _tokenIds.length, "every destination should exactly have one token ID.");
require(bridgeFee <= msg.value, "Not enough ether");
(bool success, ) = payable(moderatorAddress).call{
value: bridgeFee
}("");
require(success);
uint64 i;
for (i = 0; i < _dstChainIds.length; i++) {
_send(_from, _dstChainIds[i], _toAddress, _toSingletonArray(_tokenIds[i]), _refundAddress, _zroPaymentAddress, _adapterParams);
}
}
function estimateBatchBridgeFee(uint16[] memory _dstChainIds, bytes memory _toAddress, uint[] memory _tokenIds) public view returns (uint) {
require(_dstChainIds.length == _tokenIds.length, "every destination should exactly have one token ID.");
uint totalFee = 0;
uint16 lzVersion = 1;
uint256 lzValue = 350000;
bytes memory _adapterParams = abi.encodePacked(lzVersion, lzValue);
uint64 i;
for (i = 0; i < _dstChainIds.length; i++) {
(uint nativeFee,) = estimateSendFee(_dstChainIds[i], _toAddress, _tokenIds[i], false, _adapterParams);
totalFee += nativeFee;
}
return totalFee;
}
function setMintFee(uint _fee) external onlyOwner {
mintFee = _fee;
}
function setBridgeFee(uint _fee) external onlyOwner {
bridgeFee = _fee;
}
function setModerator(address _moderator) public onlyOwner {
moderatorAddress = _moderator;
}
function _baseURI() internal view virtual override returns (string memory) {
return baseTokenURI;
}
function setBaseURI(string memory _baseTokenURI) public onlyOwner {
baseTokenURI = _baseTokenURI;
}
function setBaseExtension(string memory _newBaseExtension) external onlyOwner {
baseExtension = _newBaseExtension;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory currentBaseURI = _baseURI();
return
bytes(currentBaseURI).length > 0
? string(
abi.encodePacked(
currentBaseURI,
tokenId.toString(),
baseExtension
)
)
: "";
}
function withdraw() public payable onlyOwner {
(bool success, ) = payable(msg.sender).call{
value: address(this).balance
}("");
require(success);
}
}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"},{"inputs":[],"name":"ERC721EnumerableForbiddenBatchMint","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ERC721OutOfBoundsIndex","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":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":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":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16[]","name":"_dstChainIds","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":"batchBridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"batchMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bridgeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"_dstChainIds","type":"uint16[]"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"estimateBatchBridgeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendBatchFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee2","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":[],"name":"mintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"moderatorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"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":"string","name":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseTokenURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setBridgeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"setDstChainIdToBatchLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"}],"name":"setDstChainIdToTransferGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"setMinGasToTransferAndStore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_moderator","type":"address"}],"name":"setModerator","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
66012c221cc6a000601555653691d6afc00060165560c0604052600060a0908152601a906200002f9082620002e7565b503480156200003d57600080fd5b5060405162005d9138038062005d918339810160408190526200006091620003b3565b6040518060400160405280601481526020017f446170704761746520627920446170704c61627300000000000000000000000081525060405180604001604052806006815260200165444c4741544560d01b8152508585838383838080620000d7620000d1620001ee60201b60201c565b620001f2565b6001600160a01b031660805250600160065581620001475760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b606482015260840160405180910390fd5b50600755600b620001598382620002e7565b50600c620001688282620002e7565b505050601786905550505060188290555060408051808201909152601481527f68747470733a2f2f6761732e7a6b6c2e6170702f0000000000000000000000006020820152601990620001bc9082620002e7565b5050601b80546001600160a01b031916733772f434d796a1b974e9b2cd37055a075f3450be1790555062000400915050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200026d57607f821691505b6020821081036200028e57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002e257600081815260208120601f850160051c81016020861015620002bd5750805b601f850160051c820191505b81811015620002de57828155600101620002c9565b5050505b505050565b81516001600160401b0381111562000303576200030362000242565b6200031b8162000314845462000258565b8462000294565b602080601f8311600181146200035357600084156200033a5750858301515b600019600386901b1c1916600185901b178555620002de565b600085815260208120601f198616915b82811015620003845788860151825594840194600190910190840162000363565b5085821015620003a35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008060008060808587031215620003ca57600080fd5b845160208601519094506001600160a01b0381168114620003ea57600080fd5b6040860151606090960151949790965092505050565b6080516159366200045b60003960008181610b2201528181610da6015281816110aa0152818161132e0152818161169e01528181611958015281816125ee01528181612a9801528181612bcb0152613d4201526159366000f3fe60806040526004361061041a5760003560e01c806382b12dd71161021e578063baf3292d11610123578063df2a5b3b116100ab578063eddd0d9c1161007a578063eddd0d9c14610cf6578063f235364114610d16578063f2fde38b14610d36578063f5ecbdbc14610d56578063fa25f9b614610d7657600080fd5b8063df2a5b3b14610c57578063e1d4c87014610c77578063e985e9c514610c8d578063eb8d72b714610cd657600080fd5b8063cbed8b9c116100f2578063cbed8b9c14610bcf578063d12473a514610bef578063d1deba1f14610c0f578063d547cfb714610c22578063da3ef23f14610c3757600080fd5b8063baf3292d14610b64578063c446183414610b84578063c668286214610b9a578063c87b56dd14610baf57600080fd5b80639c3e0d6a116101a6578063a6c3d16511610175578063a6c3d16514610ab5578063ab3ffb9314610ad5578063af3fb21c14610ae8578063b353aaa714610b10578063b88d4fde14610b4457600080fd5b80639c3e0d6a14610a355780639ea5d6b114610a555780639f38369a14610a75578063a22cb46514610a9557600080fd5b80638da5cb5b116101ed5780638da5cb5b146109a25780638ffa1f2a146109c0578063950c8a74146109e057806395d89b4114610a00578063998cdf8314610a1557600080fd5b806382b12dd71461092e5780638467be0d146109445780638945adfd146109575780638cfd8f5c1461096a57600080fd5b80633f1f4fa4116103245780636352211e116102ac57806370a082311161027b57806370a0823114610899578063715018a6146108b957806372cf5af2146108ce5780637533d788146108ee57806375bba1891461090e57600080fd5b80636352211e1461082357806366ad5c8a146108435780636aa99da3146108635780636d4135381461087957600080fd5b80634ac3f4ff116102f35780634ac3f4ff146107545780634f6ccce71461078157806351905636146107a157806355f804b3146107b45780635b8c41e6146107d457600080fd5b80633f1f4fa4146106d157806342842e0e146106fe57806342d65a8d1461071e578063482881901461073e57600080fd5b80631249c58b116103a757806323b872dd1161037657806323b872dd146106345780632a205e3d146106545780632f745c59146106895780633ccfd60b146106a95780633d8b38f6146106b157600080fd5b80631249c58b1461057057806313966db51461057857806318160ddd1461059c57806322a3ecf9146105b157600080fd5b8063081812fc116103ee578063081812fc146104b8578063095ea7b3146104f05780630b4cad4c146105105780630df374831461053057806310ddb1371461055057600080fd5b80621d35671461041f57806301ffc9a71461044157806306fdde031461047657806307e0db1714610498575b600080fd5b34801561042b57600080fd5b5061043f61043a366004614477565b610da3565b005b34801561044d57600080fd5b5061046161045c366004614520565b610fd4565b60405190151581526020015b60405180910390f35b34801561048257600080fd5b5061048b610ff7565b60405161046d919061458d565b3480156104a457600080fd5b5061043f6104b33660046145a0565b611089565b3480156104c457600080fd5b506104d86104d33660046145bb565b611112565b6040516001600160a01b03909116815260200161046d565b3480156104fc57600080fd5b5061043f61050b3660046145f4565b611139565b34801561051c57600080fd5b5061043f61052b3660046145bb565b61124e565b34801561053c57600080fd5b5061043f61054b366004614620565b6112ee565b34801561055c57600080fd5b5061043f61056b3660046145a0565b61130d565b61043f611365565b34801561058457600080fd5b5061058e60155481565b60405190815260200161046d565b3480156105a857600080fd5b5060135461058e565b3480156105bd57600080fd5b506106056105cc3660046145bb565b600a6020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b039093166020850152918301521515606082015260800161046d565b34801561064057600080fd5b5061043f61064f36600461463c565b61147b565b34801561066057600080fd5b5061067461066f366004614758565b6114ad565b6040805192835260208301919091520161046d565b34801561069557600080fd5b5061058e6106a43660046145f4565b6114d3565b61043f611538565b3480156106bd57600080fd5b506104616106cc3660046147e6565b611598565b3480156106dd57600080fd5b5061058e6106ec3660046145a0565b60036020526000908152604090205481565b34801561070a57600080fd5b5061043f61071936600461463c565b611664565b34801561072a57600080fd5b5061043f6107393660046147e6565b61167f565b34801561074a57600080fd5b5061058e60075481565b34801561076057600080fd5b5061058e61076f3660046145a0565b60086020526000908152604090205481565b34801561078d57600080fd5b5061058e61079c3660046145bb565b611705565b61043f6107af366004614838565b61175e565b3480156107c057600080fd5b5061043f6107cf3660046148f1565b611803565b3480156107e057600080fd5b5061058e6107ef366004614939565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561082f57600080fd5b506104d861083e3660046145bb565b611817565b34801561084f57600080fd5b5061043f61085e366004614477565b611877565b34801561086f57600080fd5b5061058e60175481565b34801561088557600080fd5b50610674610894366004614996565b611953565b3480156108a557600080fd5b5061058e6108b4366004614a1a565b6119f7565b3480156108c557600080fd5b5061043f611a7d565b3480156108da57600080fd5b5061058e6108e9366004614b22565b611a91565b3480156108fa57600080fd5b5061048b6109093660046145a0565b611b82565b34801561091a57600080fd5b5061043f610929366004614a1a565b611c1c565b34801561093a57600080fd5b5061058e60165481565b61043f6109523660046145bb565b611c46565b61043f610965366004614ba9565b611ddd565b34801561097657600080fd5b5061058e610985366004614c6b565b600260209081526000928352604080842090915290825290205481565b3480156109ae57600080fd5b506000546001600160a01b03166104d8565b3480156109cc57600080fd5b5061043f6109db366004614c9e565b611f0f565b3480156109ec57600080fd5b506004546104d8906001600160a01b031681565b348015610a0c57600080fd5b5061048b612157565b348015610a2157600080fd5b5061043f610a303660046145bb565b612166565b348015610a4157600080fd5b50601b546104d8906001600160a01b031681565b348015610a6157600080fd5b5061043f610a70366004614620565b612173565b348015610a8157600080fd5b5061048b610a903660046145a0565b61222a565b348015610aa157600080fd5b5061043f610ab0366004614cd2565b612340565b348015610ac157600080fd5b5061043f610ad03660046147e6565b61234b565b61043f610ae3366004614cfe565b6123d4565b348015610af457600080fd5b50610afd600181565b60405161ffff909116815260200161046d565b348015610b1c57600080fd5b506104d87f000000000000000000000000000000000000000000000000000000000000000081565b348015610b5057600080fd5b5061043f610b5f366004614d9d565b612467565b348015610b7057600080fd5b5061043f610b7f366004614a1a565b61249f565b348015610b9057600080fd5b5061058e61271081565b348015610ba657600080fd5b5061048b6124f5565b348015610bbb57600080fd5b5061048b610bca3660046145bb565b612502565b348015610bdb57600080fd5b5061043f610bea366004614dfc565b6125cf565b348015610bfb57600080fd5b5061043f610c0a366004614620565b612659565b61043f610c1d366004614477565b612709565b348015610c2e57600080fd5b5061048b61291f565b348015610c4357600080fd5b5061043f610c523660046148f1565b61292c565b348015610c6357600080fd5b5061043f610c72366004614e6a565b612940565b348015610c8357600080fd5b5061058e60185481565b348015610c9957600080fd5b50610461610ca8366004614ea6565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b348015610ce257600080fd5b5061043f610cf13660046147e6565b6129f2565b348015610d0257600080fd5b5061043f610d113660046145bb565b612a4c565b348015610d2257600080fd5b50610674610d31366004614edf565b612a59565b348015610d4257600080fd5b5061043f610d51366004614a1a565b612b24565b348015610d6257600080fd5b5061048b610d71366004614f58565b612b9a565b348015610d8257600080fd5b5061058e610d913660046145a0565b60096020526000908152604090205481565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614610e205760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610e3e90614fa5565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6a90614fa5565b8015610eb75780601f10610e8c57610100808354040283529160200191610eb7565b820191906000526020600020905b815481529060010190602001808311610e9a57829003601f168201915b50505050509050805186869050148015610ed2575060008151115b8015610efa575080516020820120604051610ef09088908890614fdf565b6040518091039020145b610f555760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610e17565b610fcb8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612c4d92505050565b50505050505050565b60006001600160e01b031982161580610ff15750610ff182612cc6565b92915050565b6060600b805461100690614fa5565b80601f016020809104026020016040519081016040528092919081815260200182805461103290614fa5565b801561107f5780601f106110545761010080835404028352916020019161107f565b820191906000526020600020905b81548152906001019060200180831161106257829003601f168201915b5050505050905090565b611091612ceb565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b1580156110f757600080fd5b505af115801561110b573d6000803e3d6000fd5b5050505050565b600061111d82612d45565b506000908152600f60205260409020546001600160a01b031690565b600061114482611817565b9050806001600160a01b0316836001600160a01b0316036111b15760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610e17565b336001600160a01b03821614806111cd57506111cd8133610ca8565b61123f5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610e17565b6112498383612d95565b505050565b611256612ceb565b600081116112b25760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b6064820152608401610e17565b60078190556040518181527ffebbc4f8bb9ec2313950c718d43123124b15778efda4c1f1d529de2995b4f34d906020015b60405180910390a150565b6112f6612ceb565b61ffff909116600090815260036020526040902055565b611315612ceb565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb137906024016110dd565b6015543410156113af5760405162461bcd60e51b8152602060048201526015602482015274139bdd08195b9bdd59da08195d1a195c881cd95b9d605a1b6044820152606401610e17565b60185460175411156113f65760405162461bcd60e51b815260206004820152601060248201526f13585e081b5a5b9d081c995858da195960821b6044820152606401610e17565b601b546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611443576040519150601f19603f3d011682016040523d82523d6000602084013e611448565b606091505b505090508061145657600080fd5b60178054908190600061146883615005565b91905055506114773382612e03565b5050565b611486335b82612e1d565b6114a25760405162461bcd60e51b8152600401610e179061501e565b611249838383612e9b565b6000806114c587876114be8861300c565b8787612a59565b915091509550959350505050565b60006114de836119f7565b821061150f5760405163295f44f760e21b81526001600160a01b038416600482015260248101839052604401610e17565b506001600160a01b03919091166000908152601160209081526040808320938352929052205490565b611540612ceb565b604051600090339047908381818185875af1925050503d8060008114611582576040519150601f19603f3d011682016040523d82523d6000602084013e611587565b606091505b505090508061159557600080fd5b50565b61ffff8316600090815260016020526040812080548291906115b990614fa5565b80601f01602080910402602001604051908101604052809291908181526020018280546115e590614fa5565b80156116325780601f1061160757610100808354040283529160200191611632565b820191906000526020600020905b81548152906001019060200180831161161557829003601f168201915b505050505090508383604051611649929190614fdf565b60405180910390208180519060200120149150509392505050565b61124983838360405180602001604052806000815250612467565b611687612ceb565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d906116d790869086908690600401615094565b600060405180830381600087803b1580156116f157600080fd5b505af1158015610fcb573d6000803e3d6000fd5b600061171060135490565b82106117395760405163295f44f760e21b81526000600482015260248101839052604401610e17565b6013828154811061174c5761174c6150b2565b90600052602060002001549050919050565b3460165411156117805760405162461bcd60e51b8152600401610e17906150c8565b601b546016546040516000926001600160a01b031691908381818185875af1925050503d80600081146117cf576040519150601f19603f3d011682016040523d82523d6000602084013e6117d4565b606091505b50509050806117e257600080fd5b6117f98888886117f18961300c565b888888613057565b5050505050505050565b61180b612ceb565b60196114778282615138565b6000818152600d60205260408120546001600160a01b031680610ff15760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610e17565b3330146118d55760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610e17565b61194b8686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f89018190048102820181019092528781528993509150879087908190840183828082843760009201919091525061328392505050565b505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340a7bb1087308888886040518663ffffffff1660e01b81526004016119aa9594939291906151f7565b6040805180830381865afa1580156119c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ea919061524b565b9150915094509492505050565b60006001600160a01b038216611a615760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610e17565b506001600160a01b03166000908152600e602052604090205490565b611a85612ceb565b611a8f6000613414565b565b60008151845114611ab45760405162461bcd60e51b8152600401610e179061526f565b604051600160f01b60208201526205573060228201819052600091600191908390604201604051602081830303815290604052905060005b8851816001600160401b03161015611b75576000611b528a836001600160401b031681518110611b1e57611b1e6150b2565b60200260200101518a8a856001600160401b031681518110611b4257611b426150b2565b60200260200101516000876114ad565b509050611b5f81876152c2565b9550508080611b6d906152d5565b915050611aec565b5092979650505050505050565b60016020526000908152604090208054611b9b90614fa5565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc790614fa5565b8015611c145780601f10611be957610100808354040283529160200191611c14565b820191906000526020600020905b815481529060010190602001808311611bf757829003601f168201915b505050505081565b611c24612ceb565b601b80546001600160a01b0319166001600160a01b0392909216919091179055565b60008111611c8e5760405162461bcd60e51b815260206004820152601560248201527421b0b73737ba1036b4b73a10181030b6b7bab73a1760591b6044820152606401610e17565b80601554611c9c91906152fb565b341015611ce35760405162461bcd60e51b8152602060048201526015602482015274139bdd08195b9bdd59da08195d1a195c881cd95b9d605a1b6044820152606401610e17565b60185481601754611cf491906152c2565b1115611d355760405162461bcd60e51b815260206004820152601060248201526f13585e081b5a5b9d081c995858da195960821b6044820152606401610e17565b601b546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611d82576040519150601f19603f3d011682016040523d82523d6000602084013e611d87565b606091505b5050905080611d9557600080fd5b60005b82816001600160401b0316101561124957601780549081906000611dbb83615005565b9190505550611dca3382612e03565b5080611dd5816152d5565b915050611d98565b8351865114611dfe5760405162461bcd60e51b8152600401610e179061526f565b346016541115611e205760405162461bcd60e51b8152600401610e17906150c8565b601b546016546040516000926001600160a01b031691908381818185875af1925050503d8060008114611e6f576040519150601f19603f3d011682016040523d82523d6000602084013e611e74565b606091505b5050905080611e8257600080fd5b60005b8751816001600160401b03161015611f0457611ef28989836001600160401b031681518110611eb657611eb66150b2565b602002602001015189611eea8a866001600160401b031681518110611edd57611edd6150b2565b602002602001015161300c565b898989613057565b80611efc816152d5565b915050611e85565b505050505050505050565b611f17613464565b80516020808301919091206000818152600a90925260409091206002015460ff16611f785760405162461bcd60e51b81526020600482015260116024820152701b9bc818dc99591a5d1cc81cdd1bdc9959607a1b6044820152606401610e17565b600082806020019051810190611f8e9190615357565b6000848152600a602052604081208054600190910154929450909250611fca9161ffff8216916201000090046001600160a01b031690856134bd565b6000848152600a6020526040902060010154909150811161203f5760405162461bcd60e51b815260206004820152602960248201527f6e6f7420656e6f7567682067617320746f2070726f6365737320637265646974604482015268103a3930b739b332b960b91b6064820152608401610e17565b815181036120b6576000838152600a602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba233906120a99085815260200190565b60405180910390a161214a565b604080516080810182526000858152600a6020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b5050506115956001600655565b6060600c805461100690614fa5565b61216e612ceb565b601655565b61217b612ceb565b600081116121d65760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610e17565b61ffff8216600081815260086020908152604091829020849055815192835282018390527f7315f7654d594ead24a30160ed9ba2d23247f543016b918343591e93d7afdb6d91015b60405180910390a15050565b61ffff811660009081526001602052604081208054606092919061224d90614fa5565b80601f016020809104026020016040519081016040528092919081815260200182805461227990614fa5565b80156122c65780601f1061229b576101008083540402835291602001916122c6565b820191906000526020600020905b8154815290600101906020018083116122a957829003601f168201915b50505050509050805160000361231e5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610e17565b6123396000601483516123319190615411565b839190613509565b9392505050565b611477338383613616565b612353612ceb565b81813060405160200161236893929190615424565b60408051601f1981840301815291815261ffff85166000908152600160205220906123939082615138565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce8383836040516123c793929190615094565b60405180910390a1505050565b3460165411156123f65760405162461bcd60e51b8152600401610e17906150c8565b601b546016546040516000926001600160a01b031691908381818185875af1925050503d8060008114612445576040519150601f19603f3d011682016040523d82523d6000602084013e61244a565b606091505b505090508061245857600080fd5b6117f988888888888888613057565b6124713383612e1d565b61248d5760405162461bcd60e51b8152600401610e179061501e565b612499848484846136e4565b50505050565b6124a7612ceb565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b906020016112e3565b601a8054611b9b90614fa5565b606061250d82613717565b6125715760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610e17565b600061257b613734565b9050600081511161259b5760405180602001604052806000815250612339565b806125a584613743565b601a6040516020016125b99392919061544a565b6040516020818303038152906040529392505050565b6125d7612ceb565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c9061262b90889088908890889088906004016154ea565b600060405180830381600087803b15801561264557600080fd5b505af1158015611f04573d6000803e3d6000fd5b612661612ceb565b600081116126bd5760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610e17565b61ffff8216600081815260096020908152604091829020849055815192835282018390527fc46df2983228ac2d9754e94a0d565e6671665dc8ad38602bc8e544f0685a29fb910161221e565b61ffff8616600090815260056020526040808220905161272c9088908890614fdf565b90815260408051602092819003830190206001600160401b038716600090815292529020549050806127ac5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610e17565b8083836040516127bd929190614fdf565b60405180910390201461281c5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610e17565b61ffff8716600090815260056020526040808220905161283f9089908990614fdf565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f880182900482028301820190528682526128d7918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061328392505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5878787878560405161290e959493929190615523565b60405180910390a150505050505050565b60198054611b9b90614fa5565b612934612ceb565b601a6114778282615138565b612948612ceb565b600081116129905760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b6044820152606401610e17565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0906060016123c7565b6129fa612ceb565b61ffff83166000908152600160205260409020612a1882848361555e565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab8383836040516123c793929190615094565b612a54612ceb565b601555565b60008060008686604051602001612a71929190615658565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb1090612ad5908b90309086908b908b906004016151f7565b6040805180830381865afa158015612af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b15919061524b565b92509250509550959350505050565b612b2c612ceb565b6001600160a01b038116612b915760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610e17565b61159581613414565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc90608401600060405180830381865afa158015612c1a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c429190810190615686565b90505b949350505050565b600080612cb05a60966366ad5c8a60e01b89898989604051602401612c7594939291906156ba565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152309291906137d5565b915091508161194b5761194b868686868561385f565b60006001600160e01b0319821663780e9d6360e01b1480610ff15750610ff1826138fc565b6000546001600160a01b03163314611a8f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610e17565b612d4e81613717565b6115955760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610e17565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612dca82611817565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61147782826040518060200160405280600081525061393c565b600080612e2983611817565b9050806001600160a01b0316846001600160a01b03161480612e7057506001600160a01b0380821660009081526010602090815260408083209388168352929052205460ff165b80612c455750836001600160a01b0316612e8984611112565b6001600160a01b031614949350505050565b826001600160a01b0316612eae82611817565b6001600160a01b031614612ed45760405162461bcd60e51b8152600401610e17906156f8565b6001600160a01b038216612f365760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610e17565b612f43838383600161396f565b826001600160a01b0316612f5682611817565b6001600160a01b031614612f7c5760405162461bcd60e51b8152600401610e17906156f8565b6000818152600f6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600e8552838620805460001901905590871680865283862080546001019055868652600d90945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110613046576130466150b2565b602090810291909101015292915050565b600084511161309e5760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610e17565b8351600114806130c2575061ffff8616600090815260086020526040902054845111155b6131195760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610e17565b60005b845181101561315c5761314a88888888858151811061313d5761313d6150b2565b6020026020010151613a4f565b8061315481615005565b91505061311c565b5060008585604051602001613172929190615658565b604051602081830303815290604052905060006131928883600086611953565b509050803410156131de5760405162461bcd60e51b8152602060048201526016602482015275139bdd08195b9bdd59da0819d85cc81d1bc81cd95b9960521b6044820152606401610e17565b855161ffff891660009081526009602052604090205461320e918a91600191879161320991906152fb565b613b3a565b61321c888387878786613c19565b8660405161322a919061573d565b6040518091039020896001600160a01b03168961ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a896040516132709190615759565b60405180910390a4505050505050505050565b6000808280602001905181019061329a9190615357565b91509150806000815181106132b1576132b16150b2565b60200260200101516000036132c7575050612499565b601482015160006132da888383866134bd565b905082518110156133ae5784516020808701919091206040805160808101825261ffff808d1682526001600160a01b038088168387019081528385018881526001606086018181526000898152600a909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad7906133a4908390899061576c565b60405180910390a1505b816001600160a01b0316876040516133c6919061573d565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d990265866040516134029190615759565b60405180910390a45050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6002600654036134b65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610e17565b6002600655565b6000825b8251811015612c42576007545a10612c42576134f786868584815181106134ea576134ea6150b2565b6020026020010151613dbe565b8061350181615005565b9150506134c1565b60608161351781601f6152c2565b10156135565760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610e17565b61356082846152c2565b845110156135a45760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610e17565b6060821580156135c3576040519150600082526020820160405261360d565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156135fc5780518352602092830192016135e4565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b0316036136775760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610e17565b6001600160a01b03838116600081815260106020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6136ef848484612e9b565b6136fb84848484613e1e565b6124995760405162461bcd60e51b8152600401610e1790615785565b6000908152600d60205260409020546001600160a01b0316151590565b60606019805461100690614fa5565b6060600061375083613f1c565b60010190506000816001600160401b0381111561376f5761376f61467d565b6040519080825280601f01601f191660200182016040528015613799576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846137a357509392505050565b6000606060008060008661ffff166001600160401b038111156137fa576137fa61467d565b6040519080825280601f01601f191660200182016040528015613824576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613846578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff16815260200190815260200160002085604051613890919061573d565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c906138ed90879087908790879087906157d7565b60405180910390a15050505050565b60006001600160e01b031982166380ac58cd60e01b148061392d57506001600160e01b03198216635b5e139f60e01b145b80610ff15750610ff182613ff4565b6139468383614029565b6139536000848484613e1e565b6112495760405162461bcd60e51b8152600401610e1790615785565b6001811115613991576040516359171fc160e01b815260040160405180910390fd5b816001600160a01b0385166139ed576139e881601380546000838152601460205260408120829055600182018355919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900155565b613a10565b836001600160a01b0316856001600160a01b031614613a1057613a1085826141a4565b6001600160a01b038416613a2c57613a2781614241565b61110b565b846001600160a01b0316846001600160a01b03161461110b5761110b84826142f0565b613a5833611480565b613abb5760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610e17565b836001600160a01b0316613ace82611817565b6001600160a01b031614613b2f5760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610e17565b612499843083612e9b565b6000613b4583614334565b61ffff808716600090815260026020908152604080832093891683529290529081205491925090613b779084906152c2565b905060008111613bc95760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610e17565b8082101561194b5760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610e17565b61ffff861660009081526001602052604081208054613c3790614fa5565b80601f0160208091040260200160405190810160405280929190818152602001828054613c6390614fa5565b8015613cb05780601f10613c8557610100808354040283529160200191613cb0565b820191906000526020600020905b815481529060010190602001808311613c9357829003601f168201915b505050505090508051600003613d215760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610e17565b613d2c878751614390565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c5803100908490613d83908b9086908c908c908c908c90600401615829565b6000604051808303818588803b158015613d9c57600080fd5b505af1158015613db0573d6000803e3d6000fd5b505050505050505050505050565b613dc781613717565b1580613df35750613dd781613717565b8015613df3575030613de882611817565b6001600160a01b0316145b613dfc57600080fd5b613e0581613717565b613e13576112498282612e03565b611249308383612e9b565b60006001600160a01b0384163b15613f1457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613e62903390899088908890600401615890565b6020604051808303816000875af1925050508015613e9d575060408051601f3d908101601f19168201909252613e9a918101906158cd565b60015b613efa573d808015613ecb576040519150601f19603f3d011682016040523d82523d6000602084013e613ed0565b606091505b508051600003613ef25760405162461bcd60e51b8152600401610e1790615785565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612c45565b506001612c45565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310613f5b5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310613f87576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310613fa557662386f26fc10000830492506010015b6305f5e1008310613fbd576305f5e100830492506008015b6127108310613fd157612710830492506004015b60648310613fe3576064830492506002015b600a8310610ff15760010192915050565b60006001600160e01b031982166322bac5d960e01b1480610ff157506301ffc9a760e01b6001600160e01b0319831614610ff1565b6001600160a01b03821661407f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610e17565b61408881613717565b156140d55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610e17565b6140e360008383600161396f565b6140ec81613717565b156141395760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610e17565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016141b1846119f7565b6141bb9190615411565b60008381526012602052604090205490915080821461420e576001600160a01b03841660009081526011602090815260408083208584528252808320548484528184208190558352601290915290208190555b5060009182526012602090815260408084208490556001600160a01b039094168352601181528383209183525290812055565b60135460009061425390600190615411565b6000838152601460205260408120546013805493945090928490811061427b5761427b6150b2565b90600052602060002001549050806013838154811061429c5761429c6150b2565b60009182526020808320909101929092558281526014909152604080822084905585825281205560138054806142d4576142d46158ea565b6001900381819060005260206000200160009055905550505050565b60006142fb836119f7565b6001600160a01b039093166000908152601160209081526040808320868452825280832085905593825260129052919091209190915550565b60006022825110156143885760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610e17565b506022015190565b61ffff8216600090815260036020526040812054908190036143b157506127105b808211156112495760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610e17565b803561ffff8116811461441357600080fd5b919050565b60008083601f84011261442a57600080fd5b5081356001600160401b0381111561444157600080fd5b60208301915083602082850101111561445957600080fd5b9250929050565b80356001600160401b038116811461441357600080fd5b6000806000806000806080878903121561449057600080fd5b61449987614401565b955060208701356001600160401b03808211156144b557600080fd5b6144c18a838b01614418565b90975095508591506144d560408a01614460565b945060608901359150808211156144eb57600080fd5b506144f889828a01614418565b979a9699509497509295939492505050565b6001600160e01b03198116811461159557600080fd5b60006020828403121561453257600080fd5b81356123398161450a565b60005b83811015614558578181015183820152602001614540565b50506000910152565b6000815180845261457981602086016020860161453d565b601f01601f19169290920160200192915050565b6020815260006123396020830184614561565b6000602082840312156145b257600080fd5b61233982614401565b6000602082840312156145cd57600080fd5b5035919050565b6001600160a01b038116811461159557600080fd5b8035614413816145d4565b6000806040838503121561460757600080fd5b8235614612816145d4565b946020939093013593505050565b6000806040838503121561463357600080fd5b61461283614401565b60008060006060848603121561465157600080fd5b833561465c816145d4565b9250602084013561466c816145d4565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156146bb576146bb61467d565b604052919050565b60006001600160401b038211156146dc576146dc61467d565b50601f01601f191660200190565b60006146fd6146f8846146c3565b614693565b905082815283838301111561471157600080fd5b828260208301376000602084830101529392505050565b600082601f83011261473957600080fd5b612339838335602085016146ea565b8035801515811461441357600080fd5b600080600080600060a0868803121561477057600080fd5b61477986614401565b945060208601356001600160401b038082111561479557600080fd5b6147a189838a01614728565b9550604088013594506147b660608901614748565b935060808801359150808211156147cc57600080fd5b506147d988828901614728565b9150509295509295909350565b6000806000604084860312156147fb57600080fd5b61480484614401565b925060208401356001600160401b0381111561481f57600080fd5b61482b86828701614418565b9497909650939450505050565b600080600080600080600060e0888a03121561485357600080fd5b873561485e816145d4565b965061486c60208901614401565b955060408801356001600160401b038082111561488857600080fd5b6148948b838c01614728565b965060608a0135955060808a013591506148ad826145d4565b90935060a0890135906148bf826145d4565b90925060c089013590808211156148d557600080fd5b506148e28a828b01614728565b91505092959891949750929550565b60006020828403121561490357600080fd5b81356001600160401b0381111561491957600080fd5b8201601f8101841361492a57600080fd5b612c45848235602084016146ea565b60008060006060848603121561494e57600080fd5b61495784614401565b925060208401356001600160401b0381111561497257600080fd5b61497e86828701614728565b92505061498d60408501614460565b90509250925092565b600080600080608085870312156149ac57600080fd5b6149b585614401565b935060208501356001600160401b03808211156149d157600080fd5b6149dd88838901614728565b94506149eb60408801614748565b93506060870135915080821115614a0157600080fd5b50614a0e87828801614728565b91505092959194509250565b600060208284031215614a2c57600080fd5b8135612339816145d4565b60006001600160401b03821115614a5057614a5061467d565b5060051b60200190565b600082601f830112614a6b57600080fd5b81356020614a7b6146f883614a37565b82815260059290921b84018101918181019086841115614a9a57600080fd5b8286015b84811015614abc57614aaf81614401565b8352918301918301614a9e565b509695505050505050565b600082601f830112614ad857600080fd5b81356020614ae86146f883614a37565b82815260059290921b84018101918181019086841115614b0757600080fd5b8286015b84811015614abc5780358352918301918301614b0b565b600080600060608486031215614b3757600080fd5b83356001600160401b0380821115614b4e57600080fd5b614b5a87838801614a5a565b94506020860135915080821115614b7057600080fd5b614b7c87838801614728565b93506040860135915080821115614b9257600080fd5b50614b9f86828701614ac7565b9150509250925092565b600080600080600080600060e0888a031215614bc457600080fd5b614bcd886145e9565b965060208801356001600160401b0380821115614be957600080fd5b614bf58b838c01614a5a565b975060408a0135915080821115614c0b57600080fd5b614c178b838c01614728565b965060608a0135915080821115614c2d57600080fd5b614c398b838c01614ac7565b9550614c4760808b016145e9565b9450614c5560a08b016145e9565b935060c08a01359150808211156148d557600080fd5b60008060408385031215614c7e57600080fd5b614c8783614401565b9150614c9560208401614401565b90509250929050565b600060208284031215614cb057600080fd5b81356001600160401b03811115614cc657600080fd5b612c4584828501614728565b60008060408385031215614ce557600080fd5b8235614cf0816145d4565b9150614c9560208401614748565b600080600080600080600060e0888a031215614d1957600080fd5b8735614d24816145d4565b9650614d3260208901614401565b955060408801356001600160401b0380821115614d4e57600080fd5b614d5a8b838c01614728565b965060608a0135915080821115614d7057600080fd5b614d7c8b838c01614ac7565b955060808a01359150614d8e826145d4565b819450614c5560a08b016145e9565b60008060008060808587031215614db357600080fd5b8435614dbe816145d4565b93506020850135614dce816145d4565b92506040850135915060608501356001600160401b03811115614df057600080fd5b614a0e87828801614728565b600080600080600060808688031215614e1457600080fd5b614e1d86614401565b9450614e2b60208701614401565b93506040860135925060608601356001600160401b03811115614e4d57600080fd5b614e5988828901614418565b969995985093965092949392505050565b600080600060608486031215614e7f57600080fd5b614e8884614401565b9250614e9660208501614401565b9150604084013590509250925092565b60008060408385031215614eb957600080fd5b8235614ec4816145d4565b91506020830135614ed4816145d4565b809150509250929050565b600080600080600060a08688031215614ef757600080fd5b614f0086614401565b945060208601356001600160401b0380821115614f1c57600080fd5b614f2889838a01614728565b95506040880135915080821115614f3e57600080fd5b614f4a89838a01614ac7565b94506147b660608901614748565b60008060008060808587031215614f6e57600080fd5b614f7785614401565b9350614f8560208601614401565b92506040850135614f95816145d4565b9396929550929360600135925050565b600181811c90821680614fb957607f821691505b602082108103614fd957634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b60006001820161501757615017614fef565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff84168152604060208201526000612c4260408301848661506b565b634e487b7160e01b600052603260045260246000fd5b60208082526010908201526f2737ba1032b737bab3b41032ba3432b960811b604082015260600190565b601f82111561124957600081815260208120601f850160051c810160208610156151195750805b601f850160051c820191505b8181101561194b57828155600101615125565b81516001600160401b038111156151515761515161467d565b6151658161515f8454614fa5565b846150f2565b602080601f83116001811461519a57600084156151825750858301515b600019600386901b1c1916600185901b17855561194b565b600085815260208120601f198616915b828110156151c9578886015182559484019460019091019084016151aa565b50858210156151e75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61ffff861681526001600160a01b038516602082015260a06040820181905260009061522590830186614561565b8415156060840152828103608084015261523f8185614561565b98975050505050505050565b6000806040838503121561525e57600080fd5b505080516020909101519092909150565b60208082526033908201527f65766572792064657374696e6174696f6e2073686f756c642065786163746c79604082015272103430bb329037b732903a37b5b2b71024a21760691b606082015260800190565b80820180821115610ff157610ff1614fef565b60006001600160401b038083168181036152f1576152f1614fef565b6001019392505050565b8082028115828204841417610ff157610ff1614fef565b600082601f83011261532357600080fd5b81516153316146f8826146c3565b81815284602083860101111561534657600080fd5b612c4582602083016020870161453d565b6000806040838503121561536a57600080fd5b82516001600160401b038082111561538157600080fd5b61538d86838701615312565b93506020915081850151818111156153a457600080fd5b85019050601f810186136153b757600080fd5b80516153c56146f882614a37565b81815260059190911b820183019083810190888311156153e457600080fd5b928401925b82841015615402578351825292840192908401906153e9565b80955050505050509250929050565b81810381811115610ff157610ff1614fef565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b60008451602061545d8285838a0161453d565b8551918401916154708184848a0161453d565b855492019160009061548181614fa5565b6001828116801561549957600181146154ae576154da565b60ff19841687528215158302870194506154da565b896000528560002060005b848110156154d2578154898201529083019087016154b9565b505082870194505b50929a9950505050505050505050565b600061ffff80881683528087166020840152508460408301526080606083015261551860808301848661506b565b979650505050505050565b61ffff8616815260806020820152600061554160808301868861506b565b6001600160401b0394909416604083015250606001529392505050565b6001600160401b038311156155755761557561467d565b615589836155838354614fa5565b836150f2565b6000601f8411600181146155bd57600085156155a55750838201355b600019600387901b1c1916600186901b17835561110b565b600083815260209020601f19861690835b828110156155ee57868501358255602094850194600190920191016155ce565b508682101561560b5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600081518084526020808501945080840160005b8381101561564d57815187529582019590820190600101615631565b509495945050505050565b60408152600061566b6040830185614561565b828103602084015261567d818561561d565b95945050505050565b60006020828403121561569857600080fd5b81516001600160401b038111156156ae57600080fd5b612c4584828501615312565b61ffff851681526080602082015260006156d76080830186614561565b6001600160401b038516604084015282810360608401526155188185614561565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b6000825161574f81846020870161453d565b9190910192915050565b602081526000612339602083018461561d565b828152604060208201526000612c456040830184614561565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b61ffff8616815260a0602082015260006157f460a0830187614561565b6001600160401b038616604084015282810360608401526158158186614561565b9050828103608084015261523f8185614561565b61ffff8716815260c06020820152600061584660c0830188614561565b82810360408401526158588188614561565b6001600160a01b0387811660608601528616608085015283810360a085015290506158838185614561565b9998505050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906158c390830184614561565b9695505050505050565b6000602082840312156158df57600080fd5b81516123398161450a565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220a3603628701341dad3d02bf4edc4a64f6b29ae537065be7f75fb1bb5673776a264736f6c634300081200330000000000000000000000000000000000000000000000000000000000009c400000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d32352450000000000000000000000000000000000000000000000000000000006422c4000000000000000000000000000000000000000000000000000000000068e777f
Deployed Bytecode
0x60806040526004361061041a5760003560e01c806382b12dd71161021e578063baf3292d11610123578063df2a5b3b116100ab578063eddd0d9c1161007a578063eddd0d9c14610cf6578063f235364114610d16578063f2fde38b14610d36578063f5ecbdbc14610d56578063fa25f9b614610d7657600080fd5b8063df2a5b3b14610c57578063e1d4c87014610c77578063e985e9c514610c8d578063eb8d72b714610cd657600080fd5b8063cbed8b9c116100f2578063cbed8b9c14610bcf578063d12473a514610bef578063d1deba1f14610c0f578063d547cfb714610c22578063da3ef23f14610c3757600080fd5b8063baf3292d14610b64578063c446183414610b84578063c668286214610b9a578063c87b56dd14610baf57600080fd5b80639c3e0d6a116101a6578063a6c3d16511610175578063a6c3d16514610ab5578063ab3ffb9314610ad5578063af3fb21c14610ae8578063b353aaa714610b10578063b88d4fde14610b4457600080fd5b80639c3e0d6a14610a355780639ea5d6b114610a555780639f38369a14610a75578063a22cb46514610a9557600080fd5b80638da5cb5b116101ed5780638da5cb5b146109a25780638ffa1f2a146109c0578063950c8a74146109e057806395d89b4114610a00578063998cdf8314610a1557600080fd5b806382b12dd71461092e5780638467be0d146109445780638945adfd146109575780638cfd8f5c1461096a57600080fd5b80633f1f4fa4116103245780636352211e116102ac57806370a082311161027b57806370a0823114610899578063715018a6146108b957806372cf5af2146108ce5780637533d788146108ee57806375bba1891461090e57600080fd5b80636352211e1461082357806366ad5c8a146108435780636aa99da3146108635780636d4135381461087957600080fd5b80634ac3f4ff116102f35780634ac3f4ff146107545780634f6ccce71461078157806351905636146107a157806355f804b3146107b45780635b8c41e6146107d457600080fd5b80633f1f4fa4146106d157806342842e0e146106fe57806342d65a8d1461071e578063482881901461073e57600080fd5b80631249c58b116103a757806323b872dd1161037657806323b872dd146106345780632a205e3d146106545780632f745c59146106895780633ccfd60b146106a95780633d8b38f6146106b157600080fd5b80631249c58b1461057057806313966db51461057857806318160ddd1461059c57806322a3ecf9146105b157600080fd5b8063081812fc116103ee578063081812fc146104b8578063095ea7b3146104f05780630b4cad4c146105105780630df374831461053057806310ddb1371461055057600080fd5b80621d35671461041f57806301ffc9a71461044157806306fdde031461047657806307e0db1714610498575b600080fd5b34801561042b57600080fd5b5061043f61043a366004614477565b610da3565b005b34801561044d57600080fd5b5061046161045c366004614520565b610fd4565b60405190151581526020015b60405180910390f35b34801561048257600080fd5b5061048b610ff7565b60405161046d919061458d565b3480156104a457600080fd5b5061043f6104b33660046145a0565b611089565b3480156104c457600080fd5b506104d86104d33660046145bb565b611112565b6040516001600160a01b03909116815260200161046d565b3480156104fc57600080fd5b5061043f61050b3660046145f4565b611139565b34801561051c57600080fd5b5061043f61052b3660046145bb565b61124e565b34801561053c57600080fd5b5061043f61054b366004614620565b6112ee565b34801561055c57600080fd5b5061043f61056b3660046145a0565b61130d565b61043f611365565b34801561058457600080fd5b5061058e60155481565b60405190815260200161046d565b3480156105a857600080fd5b5060135461058e565b3480156105bd57600080fd5b506106056105cc3660046145bb565b600a6020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b039093166020850152918301521515606082015260800161046d565b34801561064057600080fd5b5061043f61064f36600461463c565b61147b565b34801561066057600080fd5b5061067461066f366004614758565b6114ad565b6040805192835260208301919091520161046d565b34801561069557600080fd5b5061058e6106a43660046145f4565b6114d3565b61043f611538565b3480156106bd57600080fd5b506104616106cc3660046147e6565b611598565b3480156106dd57600080fd5b5061058e6106ec3660046145a0565b60036020526000908152604090205481565b34801561070a57600080fd5b5061043f61071936600461463c565b611664565b34801561072a57600080fd5b5061043f6107393660046147e6565b61167f565b34801561074a57600080fd5b5061058e60075481565b34801561076057600080fd5b5061058e61076f3660046145a0565b60086020526000908152604090205481565b34801561078d57600080fd5b5061058e61079c3660046145bb565b611705565b61043f6107af366004614838565b61175e565b3480156107c057600080fd5b5061043f6107cf3660046148f1565b611803565b3480156107e057600080fd5b5061058e6107ef366004614939565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561082f57600080fd5b506104d861083e3660046145bb565b611817565b34801561084f57600080fd5b5061043f61085e366004614477565b611877565b34801561086f57600080fd5b5061058e60175481565b34801561088557600080fd5b50610674610894366004614996565b611953565b3480156108a557600080fd5b5061058e6108b4366004614a1a565b6119f7565b3480156108c557600080fd5b5061043f611a7d565b3480156108da57600080fd5b5061058e6108e9366004614b22565b611a91565b3480156108fa57600080fd5b5061048b6109093660046145a0565b611b82565b34801561091a57600080fd5b5061043f610929366004614a1a565b611c1c565b34801561093a57600080fd5b5061058e60165481565b61043f6109523660046145bb565b611c46565b61043f610965366004614ba9565b611ddd565b34801561097657600080fd5b5061058e610985366004614c6b565b600260209081526000928352604080842090915290825290205481565b3480156109ae57600080fd5b506000546001600160a01b03166104d8565b3480156109cc57600080fd5b5061043f6109db366004614c9e565b611f0f565b3480156109ec57600080fd5b506004546104d8906001600160a01b031681565b348015610a0c57600080fd5b5061048b612157565b348015610a2157600080fd5b5061043f610a303660046145bb565b612166565b348015610a4157600080fd5b50601b546104d8906001600160a01b031681565b348015610a6157600080fd5b5061043f610a70366004614620565b612173565b348015610a8157600080fd5b5061048b610a903660046145a0565b61222a565b348015610aa157600080fd5b5061043f610ab0366004614cd2565b612340565b348015610ac157600080fd5b5061043f610ad03660046147e6565b61234b565b61043f610ae3366004614cfe565b6123d4565b348015610af457600080fd5b50610afd600181565b60405161ffff909116815260200161046d565b348015610b1c57600080fd5b506104d87f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d323524581565b348015610b5057600080fd5b5061043f610b5f366004614d9d565b612467565b348015610b7057600080fd5b5061043f610b7f366004614a1a565b61249f565b348015610b9057600080fd5b5061058e61271081565b348015610ba657600080fd5b5061048b6124f5565b348015610bbb57600080fd5b5061048b610bca3660046145bb565b612502565b348015610bdb57600080fd5b5061043f610bea366004614dfc565b6125cf565b348015610bfb57600080fd5b5061043f610c0a366004614620565b612659565b61043f610c1d366004614477565b612709565b348015610c2e57600080fd5b5061048b61291f565b348015610c4357600080fd5b5061043f610c523660046148f1565b61292c565b348015610c6357600080fd5b5061043f610c72366004614e6a565b612940565b348015610c8357600080fd5b5061058e60185481565b348015610c9957600080fd5b50610461610ca8366004614ea6565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b348015610ce257600080fd5b5061043f610cf13660046147e6565b6129f2565b348015610d0257600080fd5b5061043f610d113660046145bb565b612a4c565b348015610d2257600080fd5b50610674610d31366004614edf565b612a59565b348015610d4257600080fd5b5061043f610d51366004614a1a565b612b24565b348015610d6257600080fd5b5061048b610d71366004614f58565b612b9a565b348015610d8257600080fd5b5061058e610d913660046145a0565b60096020526000908152604090205481565b337f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d32352456001600160a01b031614610e205760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610e3e90614fa5565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6a90614fa5565b8015610eb75780601f10610e8c57610100808354040283529160200191610eb7565b820191906000526020600020905b815481529060010190602001808311610e9a57829003601f168201915b50505050509050805186869050148015610ed2575060008151115b8015610efa575080516020820120604051610ef09088908890614fdf565b6040518091039020145b610f555760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610e17565b610fcb8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612c4d92505050565b50505050505050565b60006001600160e01b031982161580610ff15750610ff182612cc6565b92915050565b6060600b805461100690614fa5565b80601f016020809104026020016040519081016040528092919081815260200182805461103290614fa5565b801561107f5780601f106110545761010080835404028352916020019161107f565b820191906000526020600020905b81548152906001019060200180831161106257829003601f168201915b5050505050905090565b611091612ceb565b6040516307e0db1760e01b815261ffff821660048201527f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d32352456001600160a01b0316906307e0db17906024015b600060405180830381600087803b1580156110f757600080fd5b505af115801561110b573d6000803e3d6000fd5b5050505050565b600061111d82612d45565b506000908152600f60205260409020546001600160a01b031690565b600061114482611817565b9050806001600160a01b0316836001600160a01b0316036111b15760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610e17565b336001600160a01b03821614806111cd57506111cd8133610ca8565b61123f5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610e17565b6112498383612d95565b505050565b611256612ceb565b600081116112b25760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b6064820152608401610e17565b60078190556040518181527ffebbc4f8bb9ec2313950c718d43123124b15778efda4c1f1d529de2995b4f34d906020015b60405180910390a150565b6112f6612ceb565b61ffff909116600090815260036020526040902055565b611315612ceb565b6040516310ddb13760e01b815261ffff821660048201527f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d32352456001600160a01b0316906310ddb137906024016110dd565b6015543410156113af5760405162461bcd60e51b8152602060048201526015602482015274139bdd08195b9bdd59da08195d1a195c881cd95b9d605a1b6044820152606401610e17565b60185460175411156113f65760405162461bcd60e51b815260206004820152601060248201526f13585e081b5a5b9d081c995858da195960821b6044820152606401610e17565b601b546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611443576040519150601f19603f3d011682016040523d82523d6000602084013e611448565b606091505b505090508061145657600080fd5b60178054908190600061146883615005565b91905055506114773382612e03565b5050565b611486335b82612e1d565b6114a25760405162461bcd60e51b8152600401610e179061501e565b611249838383612e9b565b6000806114c587876114be8861300c565b8787612a59565b915091509550959350505050565b60006114de836119f7565b821061150f5760405163295f44f760e21b81526001600160a01b038416600482015260248101839052604401610e17565b506001600160a01b03919091166000908152601160209081526040808320938352929052205490565b611540612ceb565b604051600090339047908381818185875af1925050503d8060008114611582576040519150601f19603f3d011682016040523d82523d6000602084013e611587565b606091505b505090508061159557600080fd5b50565b61ffff8316600090815260016020526040812080548291906115b990614fa5565b80601f01602080910402602001604051908101604052809291908181526020018280546115e590614fa5565b80156116325780601f1061160757610100808354040283529160200191611632565b820191906000526020600020905b81548152906001019060200180831161161557829003601f168201915b505050505090508383604051611649929190614fdf565b60405180910390208180519060200120149150509392505050565b61124983838360405180602001604052806000815250612467565b611687612ceb565b6040516342d65a8d60e01b81526001600160a01b037f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d323524516906342d65a8d906116d790869086908690600401615094565b600060405180830381600087803b1580156116f157600080fd5b505af1158015610fcb573d6000803e3d6000fd5b600061171060135490565b82106117395760405163295f44f760e21b81526000600482015260248101839052604401610e17565b6013828154811061174c5761174c6150b2565b90600052602060002001549050919050565b3460165411156117805760405162461bcd60e51b8152600401610e17906150c8565b601b546016546040516000926001600160a01b031691908381818185875af1925050503d80600081146117cf576040519150601f19603f3d011682016040523d82523d6000602084013e6117d4565b606091505b50509050806117e257600080fd5b6117f98888886117f18961300c565b888888613057565b5050505050505050565b61180b612ceb565b60196114778282615138565b6000818152600d60205260408120546001600160a01b031680610ff15760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610e17565b3330146118d55760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610e17565b61194b8686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f89018190048102820181019092528781528993509150879087908190840183828082843760009201919091525061328392505050565b505050505050565b6000807f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d32352456001600160a01b03166340a7bb1087308888886040518663ffffffff1660e01b81526004016119aa9594939291906151f7565b6040805180830381865afa1580156119c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ea919061524b565b9150915094509492505050565b60006001600160a01b038216611a615760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610e17565b506001600160a01b03166000908152600e602052604090205490565b611a85612ceb565b611a8f6000613414565b565b60008151845114611ab45760405162461bcd60e51b8152600401610e179061526f565b604051600160f01b60208201526205573060228201819052600091600191908390604201604051602081830303815290604052905060005b8851816001600160401b03161015611b75576000611b528a836001600160401b031681518110611b1e57611b1e6150b2565b60200260200101518a8a856001600160401b031681518110611b4257611b426150b2565b60200260200101516000876114ad565b509050611b5f81876152c2565b9550508080611b6d906152d5565b915050611aec565b5092979650505050505050565b60016020526000908152604090208054611b9b90614fa5565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc790614fa5565b8015611c145780601f10611be957610100808354040283529160200191611c14565b820191906000526020600020905b815481529060010190602001808311611bf757829003601f168201915b505050505081565b611c24612ceb565b601b80546001600160a01b0319166001600160a01b0392909216919091179055565b60008111611c8e5760405162461bcd60e51b815260206004820152601560248201527421b0b73737ba1036b4b73a10181030b6b7bab73a1760591b6044820152606401610e17565b80601554611c9c91906152fb565b341015611ce35760405162461bcd60e51b8152602060048201526015602482015274139bdd08195b9bdd59da08195d1a195c881cd95b9d605a1b6044820152606401610e17565b60185481601754611cf491906152c2565b1115611d355760405162461bcd60e51b815260206004820152601060248201526f13585e081b5a5b9d081c995858da195960821b6044820152606401610e17565b601b546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611d82576040519150601f19603f3d011682016040523d82523d6000602084013e611d87565b606091505b5050905080611d9557600080fd5b60005b82816001600160401b0316101561124957601780549081906000611dbb83615005565b9190505550611dca3382612e03565b5080611dd5816152d5565b915050611d98565b8351865114611dfe5760405162461bcd60e51b8152600401610e179061526f565b346016541115611e205760405162461bcd60e51b8152600401610e17906150c8565b601b546016546040516000926001600160a01b031691908381818185875af1925050503d8060008114611e6f576040519150601f19603f3d011682016040523d82523d6000602084013e611e74565b606091505b5050905080611e8257600080fd5b60005b8751816001600160401b03161015611f0457611ef28989836001600160401b031681518110611eb657611eb66150b2565b602002602001015189611eea8a866001600160401b031681518110611edd57611edd6150b2565b602002602001015161300c565b898989613057565b80611efc816152d5565b915050611e85565b505050505050505050565b611f17613464565b80516020808301919091206000818152600a90925260409091206002015460ff16611f785760405162461bcd60e51b81526020600482015260116024820152701b9bc818dc99591a5d1cc81cdd1bdc9959607a1b6044820152606401610e17565b600082806020019051810190611f8e9190615357565b6000848152600a602052604081208054600190910154929450909250611fca9161ffff8216916201000090046001600160a01b031690856134bd565b6000848152600a6020526040902060010154909150811161203f5760405162461bcd60e51b815260206004820152602960248201527f6e6f7420656e6f7567682067617320746f2070726f6365737320637265646974604482015268103a3930b739b332b960b91b6064820152608401610e17565b815181036120b6576000838152600a602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba233906120a99085815260200190565b60405180910390a161214a565b604080516080810182526000858152600a6020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b5050506115956001600655565b6060600c805461100690614fa5565b61216e612ceb565b601655565b61217b612ceb565b600081116121d65760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610e17565b61ffff8216600081815260086020908152604091829020849055815192835282018390527f7315f7654d594ead24a30160ed9ba2d23247f543016b918343591e93d7afdb6d91015b60405180910390a15050565b61ffff811660009081526001602052604081208054606092919061224d90614fa5565b80601f016020809104026020016040519081016040528092919081815260200182805461227990614fa5565b80156122c65780601f1061229b576101008083540402835291602001916122c6565b820191906000526020600020905b8154815290600101906020018083116122a957829003601f168201915b50505050509050805160000361231e5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610e17565b6123396000601483516123319190615411565b839190613509565b9392505050565b611477338383613616565b612353612ceb565b81813060405160200161236893929190615424565b60408051601f1981840301815291815261ffff85166000908152600160205220906123939082615138565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce8383836040516123c793929190615094565b60405180910390a1505050565b3460165411156123f65760405162461bcd60e51b8152600401610e17906150c8565b601b546016546040516000926001600160a01b031691908381818185875af1925050503d8060008114612445576040519150601f19603f3d011682016040523d82523d6000602084013e61244a565b606091505b505090508061245857600080fd5b6117f988888888888888613057565b6124713383612e1d565b61248d5760405162461bcd60e51b8152600401610e179061501e565b612499848484846136e4565b50505050565b6124a7612ceb565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b906020016112e3565b601a8054611b9b90614fa5565b606061250d82613717565b6125715760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610e17565b600061257b613734565b9050600081511161259b5760405180602001604052806000815250612339565b806125a584613743565b601a6040516020016125b99392919061544a565b6040516020818303038152906040529392505050565b6125d7612ceb565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d3235245169063cbed8b9c9061262b90889088908890889088906004016154ea565b600060405180830381600087803b15801561264557600080fd5b505af1158015611f04573d6000803e3d6000fd5b612661612ceb565b600081116126bd5760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610e17565b61ffff8216600081815260096020908152604091829020849055815192835282018390527fc46df2983228ac2d9754e94a0d565e6671665dc8ad38602bc8e544f0685a29fb910161221e565b61ffff8616600090815260056020526040808220905161272c9088908890614fdf565b90815260408051602092819003830190206001600160401b038716600090815292529020549050806127ac5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610e17565b8083836040516127bd929190614fdf565b60405180910390201461281c5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610e17565b61ffff8716600090815260056020526040808220905161283f9089908990614fdf565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f880182900482028301820190528682526128d7918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061328392505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e5878787878560405161290e959493929190615523565b60405180910390a150505050505050565b60198054611b9b90614fa5565b612934612ceb565b601a6114778282615138565b612948612ceb565b600081116129905760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b6044820152606401610e17565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0906060016123c7565b6129fa612ceb565b61ffff83166000908152600160205260409020612a1882848361555e565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab8383836040516123c793929190615094565b612a54612ceb565b601555565b60008060008686604051602001612a71929190615658565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d323524516906340a7bb1090612ad5908b90309086908b908b906004016151f7565b6040805180830381865afa158015612af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b15919061524b565b92509250509550959350505050565b612b2c612ceb565b6001600160a01b038116612b915760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610e17565b61159581613414565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d32352456001600160a01b03169063f5ecbdbc90608401600060405180830381865afa158015612c1a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c429190810190615686565b90505b949350505050565b600080612cb05a60966366ad5c8a60e01b89898989604051602401612c7594939291906156ba565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152309291906137d5565b915091508161194b5761194b868686868561385f565b60006001600160e01b0319821663780e9d6360e01b1480610ff15750610ff1826138fc565b6000546001600160a01b03163314611a8f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610e17565b612d4e81613717565b6115955760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610e17565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612dca82611817565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61147782826040518060200160405280600081525061393c565b600080612e2983611817565b9050806001600160a01b0316846001600160a01b03161480612e7057506001600160a01b0380821660009081526010602090815260408083209388168352929052205460ff165b80612c455750836001600160a01b0316612e8984611112565b6001600160a01b031614949350505050565b826001600160a01b0316612eae82611817565b6001600160a01b031614612ed45760405162461bcd60e51b8152600401610e17906156f8565b6001600160a01b038216612f365760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610e17565b612f43838383600161396f565b826001600160a01b0316612f5682611817565b6001600160a01b031614612f7c5760405162461bcd60e51b8152600401610e17906156f8565b6000818152600f6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600e8552838620805460001901905590871680865283862080546001019055868652600d90945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110613046576130466150b2565b602090810291909101015292915050565b600084511161309e5760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610e17565b8351600114806130c2575061ffff8616600090815260086020526040902054845111155b6131195760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610e17565b60005b845181101561315c5761314a88888888858151811061313d5761313d6150b2565b6020026020010151613a4f565b8061315481615005565b91505061311c565b5060008585604051602001613172929190615658565b604051602081830303815290604052905060006131928883600086611953565b509050803410156131de5760405162461bcd60e51b8152602060048201526016602482015275139bdd08195b9bdd59da0819d85cc81d1bc81cd95b9960521b6044820152606401610e17565b855161ffff891660009081526009602052604090205461320e918a91600191879161320991906152fb565b613b3a565b61321c888387878786613c19565b8660405161322a919061573d565b6040518091039020896001600160a01b03168961ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a896040516132709190615759565b60405180910390a4505050505050505050565b6000808280602001905181019061329a9190615357565b91509150806000815181106132b1576132b16150b2565b60200260200101516000036132c7575050612499565b601482015160006132da888383866134bd565b905082518110156133ae5784516020808701919091206040805160808101825261ffff808d1682526001600160a01b038088168387019081528385018881526001606086018181526000898152600a909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad7906133a4908390899061576c565b60405180910390a1505b816001600160a01b0316876040516133c6919061573d565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d990265866040516134029190615759565b60405180910390a45050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6002600654036134b65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610e17565b6002600655565b6000825b8251811015612c42576007545a10612c42576134f786868584815181106134ea576134ea6150b2565b6020026020010151613dbe565b8061350181615005565b9150506134c1565b60608161351781601f6152c2565b10156135565760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610e17565b61356082846152c2565b845110156135a45760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610e17565b6060821580156135c3576040519150600082526020820160405261360d565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156135fc5780518352602092830192016135e4565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b0316036136775760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610e17565b6001600160a01b03838116600081815260106020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6136ef848484612e9b565b6136fb84848484613e1e565b6124995760405162461bcd60e51b8152600401610e1790615785565b6000908152600d60205260409020546001600160a01b0316151590565b60606019805461100690614fa5565b6060600061375083613f1c565b60010190506000816001600160401b0381111561376f5761376f61467d565b6040519080825280601f01601f191660200182016040528015613799576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846137a357509392505050565b6000606060008060008661ffff166001600160401b038111156137fa576137fa61467d565b6040519080825280601f01601f191660200182016040528015613824576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613846578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff16815260200190815260200160002085604051613890919061573d565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c906138ed90879087908790879087906157d7565b60405180910390a15050505050565b60006001600160e01b031982166380ac58cd60e01b148061392d57506001600160e01b03198216635b5e139f60e01b145b80610ff15750610ff182613ff4565b6139468383614029565b6139536000848484613e1e565b6112495760405162461bcd60e51b8152600401610e1790615785565b6001811115613991576040516359171fc160e01b815260040160405180910390fd5b816001600160a01b0385166139ed576139e881601380546000838152601460205260408120829055600182018355919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900155565b613a10565b836001600160a01b0316856001600160a01b031614613a1057613a1085826141a4565b6001600160a01b038416613a2c57613a2781614241565b61110b565b846001600160a01b0316846001600160a01b03161461110b5761110b84826142f0565b613a5833611480565b613abb5760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610e17565b836001600160a01b0316613ace82611817565b6001600160a01b031614613b2f5760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610e17565b612499843083612e9b565b6000613b4583614334565b61ffff808716600090815260026020908152604080832093891683529290529081205491925090613b779084906152c2565b905060008111613bc95760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610e17565b8082101561194b5760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610e17565b61ffff861660009081526001602052604081208054613c3790614fa5565b80601f0160208091040260200160405190810160405280929190818152602001828054613c6390614fa5565b8015613cb05780601f10613c8557610100808354040283529160200191613cb0565b820191906000526020600020905b815481529060010190602001808311613c9357829003601f168201915b505050505090508051600003613d215760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610e17565b613d2c878751614390565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d3235245169063c5803100908490613d83908b9086908c908c908c908c90600401615829565b6000604051808303818588803b158015613d9c57600080fd5b505af1158015613db0573d6000803e3d6000fd5b505050505050505050505050565b613dc781613717565b1580613df35750613dd781613717565b8015613df3575030613de882611817565b6001600160a01b0316145b613dfc57600080fd5b613e0581613717565b613e13576112498282612e03565b611249308383612e9b565b60006001600160a01b0384163b15613f1457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613e62903390899088908890600401615890565b6020604051808303816000875af1925050508015613e9d575060408051601f3d908101601f19168201909252613e9a918101906158cd565b60015b613efa573d808015613ecb576040519150601f19603f3d011682016040523d82523d6000602084013e613ed0565b606091505b508051600003613ef25760405162461bcd60e51b8152600401610e1790615785565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612c45565b506001612c45565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310613f5b5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310613f87576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310613fa557662386f26fc10000830492506010015b6305f5e1008310613fbd576305f5e100830492506008015b6127108310613fd157612710830492506004015b60648310613fe3576064830492506002015b600a8310610ff15760010192915050565b60006001600160e01b031982166322bac5d960e01b1480610ff157506301ffc9a760e01b6001600160e01b0319831614610ff1565b6001600160a01b03821661407f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610e17565b61408881613717565b156140d55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610e17565b6140e360008383600161396f565b6140ec81613717565b156141395760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610e17565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016141b1846119f7565b6141bb9190615411565b60008381526012602052604090205490915080821461420e576001600160a01b03841660009081526011602090815260408083208584528252808320548484528184208190558352601290915290208190555b5060009182526012602090815260408084208490556001600160a01b039094168352601181528383209183525290812055565b60135460009061425390600190615411565b6000838152601460205260408120546013805493945090928490811061427b5761427b6150b2565b90600052602060002001549050806013838154811061429c5761429c6150b2565b60009182526020808320909101929092558281526014909152604080822084905585825281205560138054806142d4576142d46158ea565b6001900381819060005260206000200160009055905550505050565b60006142fb836119f7565b6001600160a01b039093166000908152601160209081526040808320868452825280832085905593825260129052919091209190915550565b60006022825110156143885760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610e17565b506022015190565b61ffff8216600090815260036020526040812054908190036143b157506127105b808211156112495760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610e17565b803561ffff8116811461441357600080fd5b919050565b60008083601f84011261442a57600080fd5b5081356001600160401b0381111561444157600080fd5b60208301915083602082850101111561445957600080fd5b9250929050565b80356001600160401b038116811461441357600080fd5b6000806000806000806080878903121561449057600080fd5b61449987614401565b955060208701356001600160401b03808211156144b557600080fd5b6144c18a838b01614418565b90975095508591506144d560408a01614460565b945060608901359150808211156144eb57600080fd5b506144f889828a01614418565b979a9699509497509295939492505050565b6001600160e01b03198116811461159557600080fd5b60006020828403121561453257600080fd5b81356123398161450a565b60005b83811015614558578181015183820152602001614540565b50506000910152565b6000815180845261457981602086016020860161453d565b601f01601f19169290920160200192915050565b6020815260006123396020830184614561565b6000602082840312156145b257600080fd5b61233982614401565b6000602082840312156145cd57600080fd5b5035919050565b6001600160a01b038116811461159557600080fd5b8035614413816145d4565b6000806040838503121561460757600080fd5b8235614612816145d4565b946020939093013593505050565b6000806040838503121561463357600080fd5b61461283614401565b60008060006060848603121561465157600080fd5b833561465c816145d4565b9250602084013561466c816145d4565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156146bb576146bb61467d565b604052919050565b60006001600160401b038211156146dc576146dc61467d565b50601f01601f191660200190565b60006146fd6146f8846146c3565b614693565b905082815283838301111561471157600080fd5b828260208301376000602084830101529392505050565b600082601f83011261473957600080fd5b612339838335602085016146ea565b8035801515811461441357600080fd5b600080600080600060a0868803121561477057600080fd5b61477986614401565b945060208601356001600160401b038082111561479557600080fd5b6147a189838a01614728565b9550604088013594506147b660608901614748565b935060808801359150808211156147cc57600080fd5b506147d988828901614728565b9150509295509295909350565b6000806000604084860312156147fb57600080fd5b61480484614401565b925060208401356001600160401b0381111561481f57600080fd5b61482b86828701614418565b9497909650939450505050565b600080600080600080600060e0888a03121561485357600080fd5b873561485e816145d4565b965061486c60208901614401565b955060408801356001600160401b038082111561488857600080fd5b6148948b838c01614728565b965060608a0135955060808a013591506148ad826145d4565b90935060a0890135906148bf826145d4565b90925060c089013590808211156148d557600080fd5b506148e28a828b01614728565b91505092959891949750929550565b60006020828403121561490357600080fd5b81356001600160401b0381111561491957600080fd5b8201601f8101841361492a57600080fd5b612c45848235602084016146ea565b60008060006060848603121561494e57600080fd5b61495784614401565b925060208401356001600160401b0381111561497257600080fd5b61497e86828701614728565b92505061498d60408501614460565b90509250925092565b600080600080608085870312156149ac57600080fd5b6149b585614401565b935060208501356001600160401b03808211156149d157600080fd5b6149dd88838901614728565b94506149eb60408801614748565b93506060870135915080821115614a0157600080fd5b50614a0e87828801614728565b91505092959194509250565b600060208284031215614a2c57600080fd5b8135612339816145d4565b60006001600160401b03821115614a5057614a5061467d565b5060051b60200190565b600082601f830112614a6b57600080fd5b81356020614a7b6146f883614a37565b82815260059290921b84018101918181019086841115614a9a57600080fd5b8286015b84811015614abc57614aaf81614401565b8352918301918301614a9e565b509695505050505050565b600082601f830112614ad857600080fd5b81356020614ae86146f883614a37565b82815260059290921b84018101918181019086841115614b0757600080fd5b8286015b84811015614abc5780358352918301918301614b0b565b600080600060608486031215614b3757600080fd5b83356001600160401b0380821115614b4e57600080fd5b614b5a87838801614a5a565b94506020860135915080821115614b7057600080fd5b614b7c87838801614728565b93506040860135915080821115614b9257600080fd5b50614b9f86828701614ac7565b9150509250925092565b600080600080600080600060e0888a031215614bc457600080fd5b614bcd886145e9565b965060208801356001600160401b0380821115614be957600080fd5b614bf58b838c01614a5a565b975060408a0135915080821115614c0b57600080fd5b614c178b838c01614728565b965060608a0135915080821115614c2d57600080fd5b614c398b838c01614ac7565b9550614c4760808b016145e9565b9450614c5560a08b016145e9565b935060c08a01359150808211156148d557600080fd5b60008060408385031215614c7e57600080fd5b614c8783614401565b9150614c9560208401614401565b90509250929050565b600060208284031215614cb057600080fd5b81356001600160401b03811115614cc657600080fd5b612c4584828501614728565b60008060408385031215614ce557600080fd5b8235614cf0816145d4565b9150614c9560208401614748565b600080600080600080600060e0888a031215614d1957600080fd5b8735614d24816145d4565b9650614d3260208901614401565b955060408801356001600160401b0380821115614d4e57600080fd5b614d5a8b838c01614728565b965060608a0135915080821115614d7057600080fd5b614d7c8b838c01614ac7565b955060808a01359150614d8e826145d4565b819450614c5560a08b016145e9565b60008060008060808587031215614db357600080fd5b8435614dbe816145d4565b93506020850135614dce816145d4565b92506040850135915060608501356001600160401b03811115614df057600080fd5b614a0e87828801614728565b600080600080600060808688031215614e1457600080fd5b614e1d86614401565b9450614e2b60208701614401565b93506040860135925060608601356001600160401b03811115614e4d57600080fd5b614e5988828901614418565b969995985093965092949392505050565b600080600060608486031215614e7f57600080fd5b614e8884614401565b9250614e9660208501614401565b9150604084013590509250925092565b60008060408385031215614eb957600080fd5b8235614ec4816145d4565b91506020830135614ed4816145d4565b809150509250929050565b600080600080600060a08688031215614ef757600080fd5b614f0086614401565b945060208601356001600160401b0380821115614f1c57600080fd5b614f2889838a01614728565b95506040880135915080821115614f3e57600080fd5b614f4a89838a01614ac7565b94506147b660608901614748565b60008060008060808587031215614f6e57600080fd5b614f7785614401565b9350614f8560208601614401565b92506040850135614f95816145d4565b9396929550929360600135925050565b600181811c90821680614fb957607f821691505b602082108103614fd957634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b60006001820161501757615017614fef565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff84168152604060208201526000612c4260408301848661506b565b634e487b7160e01b600052603260045260246000fd5b60208082526010908201526f2737ba1032b737bab3b41032ba3432b960811b604082015260600190565b601f82111561124957600081815260208120601f850160051c810160208610156151195750805b601f850160051c820191505b8181101561194b57828155600101615125565b81516001600160401b038111156151515761515161467d565b6151658161515f8454614fa5565b846150f2565b602080601f83116001811461519a57600084156151825750858301515b600019600386901b1c1916600185901b17855561194b565b600085815260208120601f198616915b828110156151c9578886015182559484019460019091019084016151aa565b50858210156151e75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61ffff861681526001600160a01b038516602082015260a06040820181905260009061522590830186614561565b8415156060840152828103608084015261523f8185614561565b98975050505050505050565b6000806040838503121561525e57600080fd5b505080516020909101519092909150565b60208082526033908201527f65766572792064657374696e6174696f6e2073686f756c642065786163746c79604082015272103430bb329037b732903a37b5b2b71024a21760691b606082015260800190565b80820180821115610ff157610ff1614fef565b60006001600160401b038083168181036152f1576152f1614fef565b6001019392505050565b8082028115828204841417610ff157610ff1614fef565b600082601f83011261532357600080fd5b81516153316146f8826146c3565b81815284602083860101111561534657600080fd5b612c4582602083016020870161453d565b6000806040838503121561536a57600080fd5b82516001600160401b038082111561538157600080fd5b61538d86838701615312565b93506020915081850151818111156153a457600080fd5b85019050601f810186136153b757600080fd5b80516153c56146f882614a37565b81815260059190911b820183019083810190888311156153e457600080fd5b928401925b82841015615402578351825292840192908401906153e9565b80955050505050509250929050565b81810381811115610ff157610ff1614fef565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b60008451602061545d8285838a0161453d565b8551918401916154708184848a0161453d565b855492019160009061548181614fa5565b6001828116801561549957600181146154ae576154da565b60ff19841687528215158302870194506154da565b896000528560002060005b848110156154d2578154898201529083019087016154b9565b505082870194505b50929a9950505050505050505050565b600061ffff80881683528087166020840152508460408301526080606083015261551860808301848661506b565b979650505050505050565b61ffff8616815260806020820152600061554160808301868861506b565b6001600160401b0394909416604083015250606001529392505050565b6001600160401b038311156155755761557561467d565b615589836155838354614fa5565b836150f2565b6000601f8411600181146155bd57600085156155a55750838201355b600019600387901b1c1916600186901b17835561110b565b600083815260209020601f19861690835b828110156155ee57868501358255602094850194600190920191016155ce565b508682101561560b5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600081518084526020808501945080840160005b8381101561564d57815187529582019590820190600101615631565b509495945050505050565b60408152600061566b6040830185614561565b828103602084015261567d818561561d565b95945050505050565b60006020828403121561569857600080fd5b81516001600160401b038111156156ae57600080fd5b612c4584828501615312565b61ffff851681526080602082015260006156d76080830186614561565b6001600160401b038516604084015282810360608401526155188185614561565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b6000825161574f81846020870161453d565b9190910192915050565b602081526000612339602083018461561d565b828152604060208201526000612c456040830184614561565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b61ffff8616815260a0602082015260006157f460a0830187614561565b6001600160401b038616604084015282810360608401526158158186614561565b9050828103608084015261523f8185614561565b61ffff8716815260c06020820152600061584660c0830188614561565b82810360408401526158588188614561565b6001600160a01b0387811660608601528616608085015283810360a085015290506158838185614561565b9998505050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906158c390830184614561565b9695505050505050565b6000602082840312156158df57600080fd5b81516123398161450a565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220a3603628701341dad3d02bf4edc4a64f6b29ae537065be7f75fb1bb5673776a264736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000009c400000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d32352450000000000000000000000000000000000000000000000000000000006422c4000000000000000000000000000000000000000000000000000000000068e777f
-----Decoded View---------------
Arg [0] : _minGasToTransfer (uint256): 40000
Arg [1] : _layerZeroEndpoint (address): 0x4EE2F9B7cf3A68966c370F3eb2C16613d3235245
Arg [2] : _startMintId (uint256): 105000000
Arg [3] : _endMintId (uint256): 109999999
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000009c40
Arg [1] : 0000000000000000000000004ee2f9b7cf3a68966c370f3eb2c16613d3235245
Arg [2] : 0000000000000000000000000000000000000000000000000000000006422c40
Arg [3] : 00000000000000000000000000000000000000000000000000000000068e777f
Deployed Bytecode Sourcemap
126402:6026:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45130:762;;;;;;;;;;-1:-1:-1;45130:762:0;;;;;:::i;:::-;;:::i;:::-;;125397:238;;;;;;;;;;-1:-1:-1;125397:238:0;;;;;:::i;:::-;;:::i;:::-;;;2124:14:1;;2117:22;2099:41;;2087:2;2072:18;125397:238:0;;;;;;;;102523:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;48428:123::-;;;;;;;;;;-1:-1:-1;48428:123:0;;;;;:::i;:::-;;:::i;104035:171::-;;;;;;;;;;-1:-1:-1;104035:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3445:32:1;;;3427:51;;3415:2;3400:18;104035:171:0;3281:203:1;103553:416:0;;;;;;;;;;-1:-1:-1;103553:416:0;;;;;:::i;:::-;;:::i;70409:321::-;;;;;;;;;;-1:-1:-1;70409:321:0;;;;;:::i;:::-;;:::i;50353:142::-;;;;;;;;;;-1:-1:-1;50353:142:0;;;;;:::i;:::-;;:::i;48559:129::-;;;;;;;;;;-1:-1:-1;48559:129:0;;;;;:::i;:::-;;:::i;127401:398::-;;;:::i;126472:35::-;;;;;;;;;;;;;;;;;;;4487:25:1;;;4475:2;4460:18;126472:35:0;4341:177:1;119782:104:0;;;;;;;;;;-1:-1:-1;119861:10:0;:17;119782:104;;64071:53;;;;;;;;;;-1:-1:-1;64071:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64071:53:0;;;;;;;;;;;4961:6:1;4949:19;;;4931:38;;-1:-1:-1;;;;;5005:32:1;;;5000:2;4985:18;;4978:60;5054:18;;;5047:34;5124:14;5117:22;5112:2;5097:18;;5090:50;4918:3;4903:19;64071:53:0;4708:438:1;104735:301:0;;;;;;;;;;-1:-1:-1;104735:301:0;;;;;:::i;:::-;;:::i;64626:320::-;;;;;;;;;;-1:-1:-1;64626:320:0;;;;;:::i;:::-;;:::i;:::-;;;;7874:25:1;;;7930:2;7915:18;;7908:34;;;;7847:18;64626:320:0;7700:248:1;119446:260:0;;;;;;;;;;-1:-1:-1;119446:260:0;;;;;:::i;:::-;;:::i;132233:192::-;;;:::i;50593:250::-;;;;;;;;;;-1:-1:-1;50593:250:0;;;;;:::i;:::-;;:::i;44672:53::-;;;;;;;;;;-1:-1:-1;44672:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;105107:151;;;;;;;;;;-1:-1:-1;105107:151:0;;;;;:::i;:::-;;:::i;48696:178::-;;;;;;;;;;-1:-1:-1;48696:178:0;;;;;:::i;:::-;;:::i;63761:39::-;;;;;;;;;;;;;;;;63877:56;;;;;;;;;;-1:-1:-1;63877:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;119963:231;;;;;;;;;;-1:-1:-1;119963:231:0;;;;;:::i;:::-;;:::i;128377:573::-;;;;;;:::i;:::-;;:::i;131444:113::-;;;;;;;;;;-1:-1:-1;131444:113:0;;;;;:::i;:::-;;:::i;56823:85::-;;;;;;;;;;-1:-1:-1;56823:85:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102233:223;;;;;;;;;;-1:-1:-1;102233:223:0;;;;;:::i;:::-;;:::i;58045:346::-;;;;;;;;;;-1:-1:-1;58045:346:0;;;;;:::i;:::-;;:::i;126560:22::-;;;;;;;;;;;;;;;;64954:280;;;;;;;;;;-1:-1:-1;64954:280:0;;;;;:::i;:::-;;:::i;101964:207::-;;;;;;;;;;-1:-1:-1;101964:207:0;;;;;:::i;:::-;;:::i;16882:103::-;;;;;;;;;;;;;:::i;130307:707::-;;;;;;;;;;-1:-1:-1;130307:707:0;;;;;:::i;:::-;;:::i;44542:51::-;;;;;;;;;;-1:-1:-1;44542:51:0;;;;;:::i;:::-;;:::i;131208:107::-;;;;;;;;;;-1:-1:-1;131208:107:0;;;;;:::i;:::-;;:::i;126514:37::-;;;;;;;;;;;;;;;;127807:562;;;;;;:::i;:::-;;:::i;129536:763::-;;;;;;:::i;:::-;;:::i;44600:65::-;;;;;;;;;;-1:-1:-1;44600:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;16241:87;;;;;;;;;;-1:-1:-1;16287:7:0;16314:6;-1:-1:-1;;;;;16314:6:0;16241:87;;68619:1009;;;;;;;;;;-1:-1:-1;68619:1009:0;;;;;:::i;:::-;;:::i;44732:23::-;;;;;;;;;;-1:-1:-1;44732:23:0;;;;-1:-1:-1;;;;;44732:23:0;;;102692:104;;;;;;;;;;;;;:::i;131113:87::-;;;;;;;;;;-1:-1:-1;131113:87:0;;;;;:::i;:::-;;:::i;126689:31::-;;;;;;;;;;-1:-1:-1;126689:31:0;;;;-1:-1:-1;;;;;126689:31:0;;;71254:351;;;;;;;;;;-1:-1:-1;71254:351:0;;;;;:::i;:::-;;:::i;49525:330::-;;;;;;;;;;-1:-1:-1;49525:330:0;;;;;:::i;:::-;;:::i;104278:155::-;;;;;;;;;;-1:-1:-1;104278:155:0;;;;;:::i;:::-;;:::i;49236:281::-;;;;;;;;;;-1:-1:-1;49236:281:0;;;;;:::i;:::-;;:::i;128958:570::-;;;;;;:::i;:::-;;:::i;63524:45::-;;;;;;;;;;;;63568:1;63524:45;;;;;17649:6:1;17637:19;;;17619:38;;17607:2;17592:18;63524:45:0;17475:188:1;44489:46:0;;;;;;;;;;;;;;;105329:279;;;;;;;;;;-1:-1:-1;105329:279:0;;;;;:::i;:::-;;:::i;49863:136::-;;;;;;;;;;-1:-1:-1;49863:136:0;;;;;:::i;:::-;;:::i;44425:55::-;;;;;;;;;;;;44475:5;44425:55;;126650:32;;;;;;;;;;;;;:::i;131703:522::-;;;;;;;;;;-1:-1:-1;131703:522:0;;;;;:::i;:::-;;:::i;48216:204::-;;;;;;;;;;-1:-1:-1;48216:204:0;;;;;:::i;:::-;;:::i;70831:359::-;;;;;;;;;;-1:-1:-1;70831:359:0;;;;;:::i;:::-;;:::i;58577:767::-;;;;;;:::i;:::-;;:::i;126617:26::-;;;;;;;;;;;;;:::i;131565:130::-;;;;;;;;;;-1:-1:-1;131565:130:0;;;;;:::i;:::-;;:::i;50007:284::-;;;;;;;;;;-1:-1:-1;50007:284:0;;;;;:::i;:::-;;:::i;126589:21::-;;;;;;;;;;;;;;;;104504:164;;;;;;;;;;-1:-1:-1;104504:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;104625:25:0;;;104601:4;104625:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;104504:164;49021:207;;;;;;;;;;-1:-1:-1;49021:207:0;;;;;:::i;:::-;;:::i;131022:83::-;;;;;;;;;;-1:-1:-1;131022:83:0;;;;;:::i;:::-;;:::i;65242:388::-;;;;;;;;;;-1:-1:-1;65242:388:0;;;;;:::i;:::-;;:::i;17140:201::-;;;;;;;;;;-1:-1:-1;17140:201:0;;;;;:::i;:::-;;:::i;47943:211::-;;;;;;;;;;-1:-1:-1;47943:211:0;;;;;:::i;:::-;;:::i;63940:57::-;;;;;;;;;;-1:-1:-1;63940:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;45130:762;15030:10;45370;-1:-1:-1;;;;;45346:35:0;;45338:78;;;;-1:-1:-1;;;45338:78:0;;21500:2:1;45338:78:0;;;21482:21:1;21539:2;21519:18;;;21512:30;21578:32;21558:18;;;21551:60;21628:18;;45338:78:0;;;;;;;;;45458:32;;;45429:26;45458:32;;;:19;:32;;;;;45429:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45664:13;:20;45642:11;;:18;;:42;:70;;;;;45711:1;45688:13;:20;:24;45642:70;:124;;;;-1:-1:-1;45742:24:0;;;;;;45716:22;;;;45726:11;;;;45716:22;:::i;:::-;;;;;;;;:50;45642:124;45634:175;;;;-1:-1:-1;;;45634:175:0;;22520:2:1;45634:175:0;;;22502:21:1;22559:2;22539:18;;;22532:30;22598:34;22578:18;;;22571:62;-1:-1:-1;;;22649:18:1;;;22642:36;22695:19;;45634:175:0;22318:402:1;45634:175:0;45822:62;45841:11;45854;;45822:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;45822:62:0;;;;;;;;;;;;;;;;;;;;;;45867:6;;-1:-1:-1;45822:62:0;-1:-1:-1;45875:8:0;;;;;;45822:62;;45875:8;;;;45822:62;;;;;;;;;-1:-1:-1;45822:18:0;;-1:-1:-1;;;45822:62:0:i;:::-;45261:631;45130:762;;;;;;:::o;125397:238::-;125522:4;-1:-1:-1;;;;;;125546:41:0;;;;:81;;;125591:36;125615:11;125591:23;:36::i;:::-;125539:88;125397:238;-1:-1:-1;;125397:238:0:o;102523:100::-;102577:13;102610:5;102603:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102523:100;:::o;48428:123::-;16127:13;:11;:13::i;:::-;48508:35:::1;::::0;-1:-1:-1;;;48508:35:0;;17649:6:1;17637:19;;48508:35:0::1;::::0;::::1;17619:38:1::0;48508:10:0::1;-1:-1:-1::0;;;;;48508:25:0::1;::::0;::::1;::::0;17592:18:1;;48508:35:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;48428:123:::0;:::o;104035:171::-;104111:7;104131:23;104146:7;104131:14;:23::i;:::-;-1:-1:-1;104174:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;104174:24:0;;104035:171::o;103553:416::-;103634:13;103650:23;103665:7;103650:14;:23::i;:::-;103634:39;;103698:5;-1:-1:-1;;;;;103692:11:0;:2;-1:-1:-1;;;;;103692:11:0;;103684:57;;;;-1:-1:-1;;;103684:57:0;;22927:2:1;103684:57:0;;;22909:21:1;22966:2;22946:18;;;22939:30;23005:34;22985:18;;;22978:62;-1:-1:-1;;;23056:18:1;;;23049:31;23097:19;;103684:57:0;22725:397:1;103684:57:0;15030:10;-1:-1:-1;;;;;103776:21:0;;;;:62;;-1:-1:-1;103801:37:0;103818:5;15030:10;104504:164;:::i;103801:37::-;103754:173;;;;-1:-1:-1;;;103754:173:0;;23329:2:1;103754:173:0;;;23311:21:1;23368:2;23348:18;;;23341:30;23407:34;23387:18;;;23380:62;23478:31;23458:18;;;23451:59;23527:19;;103754:173:0;23127:425:1;103754:173:0;103940:21;103949:2;103953:7;103940:8;:21::i;:::-;103623:346;103553:416;;:::o;70409:321::-;16127:13;:11;:13::i;:::-;70547:1:::1;70519:25;:29;70511:78;;;::::0;-1:-1:-1;;;70511:78:0;;23759:2:1;70511:78:0::1;::::0;::::1;23741:21:1::0;23798:2;23778:18;;;23771:30;23837:34;23817:18;;;23810:62;-1:-1:-1;;;23888:18:1;;;23881:34;23932:19;;70511:78:0::1;23557:400:1::0;70511:78:0::1;70600:24;:52:::0;;;70668:54:::1;::::0;4487:25:1;;;70668:54:0::1;::::0;4475:2:1;4460:18;70668:54:0::1;;;;;;;;70409:321:::0;:::o;50353:142::-;16127:13;:11;:13::i;:::-;50444:35:::1;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:43;50353:142::o;48559:129::-;16127:13;:11;:13::i;:::-;48642:38:::1;::::0;-1:-1:-1;;;48642:38:0;;17649:6:1;17637:19;;48642:38:0::1;::::0;::::1;17619::1::0;48642:10:0::1;-1:-1:-1::0;;;;;48642:28:0::1;::::0;::::1;::::0;17592:18:1;;48642:38:0::1;17475:188:1::0;127401:398:0;127464:7;;127451:9;:20;;127443:54;;;;-1:-1:-1;;;127443:54:0;;24164:2:1;127443:54:0;;;24146:21:1;24203:2;24183:18;;;24176:30;-1:-1:-1;;;24222:18:1;;;24215:51;24283:18;;127443:54:0;23962:345:1;127443:54:0;127530:9;;127516:10;;:23;;127508:52;;;;-1:-1:-1;;;127508:52:0;;24514:2:1;127508:52:0;;;24496:21:1;24553:2;24533:18;;;24526:30;-1:-1:-1;;;24572:18:1;;;24565:46;24628:18;;127508:52:0;24312:340:1;127508:52:0;127598:16;;127590:76;;127572:12;;-1:-1:-1;;;;;127598:16:0;;127642:9;;127572:12;127590:76;127572:12;127590:76;127642:9;127598:16;127590:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;127571:95;;;127685:7;127677:16;;;;;;127717:10;;;;;;127704;127738:12;127717:10;127738:12;:::i;:::-;;;;;;127763:28;127773:10;127785:5;127763:9;:28::i;:::-;127432:367;;127401:398::o;104735:301::-;104896:41;15030:10;104915:12;104929:7;104896:18;:41::i;:::-;104888:99;;;;-1:-1:-1;;;104888:99:0;;;;;;;:::i;:::-;105000:28;105010:4;105016:2;105020:7;105000:9;:28::i;64626:320::-;64792:14;64808:11;64839:99;64860:11;64873:10;64885:27;64903:8;64885:17;:27::i;:::-;64914:7;64923:14;64839:20;:99::i;:::-;64832:106;;;;64626:320;;;;;;;;:::o;119446:260::-;119534:7;119567:16;119577:5;119567:9;:16::i;:::-;119558:5;:25;119554:101;;119607:36;;-1:-1:-1;;;119607:36:0;;-1:-1:-1;;;;;25745:32:1;;119607:36:0;;;25727:51:1;25794:18;;;25787:34;;;25700:18;;119607:36:0;25553:274:1;119554:101:0;-1:-1:-1;;;;;;119672:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;119446:260::o;132233:192::-;16127:13;:11;:13::i;:::-;132308:82:::1;::::0;132290:12:::1;::::0;132316:10:::1;::::0;132354:21:::1;::::0;132290:12;132308:82;132290:12;132308:82;132354:21;132316:10;132308:82:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;132289:101;;;132409:7;132401:16;;;::::0;::::1;;132278:147;132233:192::o:0;50593:250::-;50735:32;;;50689:4;50735:32;;;:19;:32;;;;;50706:61;;50689:4;;50735:32;50706:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50823:11;;50813:22;;;;;;;:::i;:::-;;;;;;;;50795:13;50785:24;;;;;;:50;50778:57;;;50593:250;;;;;:::o;105107:151::-;105211:39;105228:4;105234:2;105238:7;105211:39;;;;;;;;;;;;:16;:39::i;48696:178::-;16127:13;:11;:13::i;:::-;48811:55:::1;::::0;-1:-1:-1;;;48811:55:0;;-1:-1:-1;;;;;48811:10:0::1;:29;::::0;::::1;::::0;:55:::1;::::0;48841:11;;48854;;;;48811:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;119963:231:::0;120029:7;120062:13;119861:10;:17;;119782:104;120062:13;120053:5;:22;120049:103;;120099:41;;-1:-1:-1;;;120099:41:0;;120130:1;120099:41;;;25727:51:1;25794:18;;;25787:34;;;25700:18;;120099:41:0;25553:274:1;120049:103:0;120169:10;120180:5;120169:17;;;;;;;;:::i;:::-;;;;;;;;;120162:24;;119963:231;;;:::o;128377:573::-;128650:9;128637;;:22;;128629:51;;;;-1:-1:-1;;;128629:51:0;;;;;;;:::i;:::-;128718:16;;128762:9;;128710:76;;128692:12;;-1:-1:-1;;;;;128718:16:0;;128762:9;128692:12;128710:76;128692:12;128710:76;128762:9;128718:16;128710:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;128691:95;;;128805:7;128797:16;;;;;;128824:118;128830:5;128837:11;128850:10;128862:27;128880:8;128862:17;:27::i;:::-;128891:14;128907:18;128927:14;128824:5;:118::i;:::-;128618:332;128377:573;;;;;;;:::o;131444:113::-;16127:13;:11;:13::i;:::-;131521:12:::1;:28;131536:13:::0;131521:12;:28:::1;:::i;102233:223::-:0;102305:7;106966:16;;;:7;:16;;;;;;-1:-1:-1;;;;;106966:16:0;;102369:56;;;;-1:-1:-1;;;102369:56:0;;29317:2:1;102369:56:0;;;29299:21:1;29356:2;29336:18;;;29329:30;-1:-1:-1;;;29375:18:1;;;29368:54;29439:18;;102369:56:0;29115:348:1;58045:346:0;15030:10;58259:4;58235:29;58227:80;;;;-1:-1:-1;;;58227:80:0;;29670:2:1;58227:80:0;;;29652:21:1;29709:2;29689:18;;;29682:30;29748:34;29728:18;;;29721:62;-1:-1:-1;;;29799:18:1;;;29792:36;29845:19;;58227:80:0;29468:402:1;58227:80:0;58318:65;58340:11;58353;;58318:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;58318:65:0;;;;;;;;;;;;;;;;;;;;;;58366:6;;-1:-1:-1;58318:65:0;-1:-1:-1;58374:8:0;;;;;;58318:65;;58374:8;;;;58318:65;;;;;;;;;-1:-1:-1;58318:21:0;;-1:-1:-1;;;58318:65:0:i;:::-;58045:346;;;;;;:::o;64954:280::-;65094:14;65110:11;65141:10;-1:-1:-1;;;;;65141:23:0;;65165:11;65186:4;65193:7;65202;65211:14;65141:85;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65134:92;;;;64954:280;;;;;;;:::o;101964:207::-;102036:7;-1:-1:-1;;;;;102064:19:0;;102056:73;;;;-1:-1:-1;;;102056:73:0;;30974:2:1;102056:73:0;;;30956:21:1;31013:2;30993:18;;;30986:30;31052:34;31032:18;;;31025:62;-1:-1:-1;;;31103:18:1;;;31096:39;31152:19;;102056:73:0;30772:405:1;102056:73:0;-1:-1:-1;;;;;;102147:16:0;;;;;:9;:16;;;;;;;101964:207::o;16882:103::-;16127:13;:11;:13::i;:::-;16947:30:::1;16974:1;16947:18;:30::i;:::-;16882:103::o:0;130307:707::-;130440:4;130488:9;:16;130465:12;:19;:39;130457:103;;;;-1:-1:-1;;;130457:103:0;;;;;;;:::i;:::-;130697:36;;-1:-1:-1;;;130697:36:0;;;31757:51:1;130650:6:0;31824:11:1;;;31817:27;;;130571:13:0;;130620:1;;130650:6;130571:13;;31860:12:1;;130697:36:0;;;;;;;;;;;;130667:66;;130754:8;130773:206;130789:12;:19;130785:1;-1:-1:-1;;;;;130785:23:0;;130773:206;;;130831:14;130850:81;130866:12;130879:1;-1:-1:-1;;;;;130866:15:0;;;;;;;;;:::i;:::-;;;;;;;130883:10;130895:9;130905:1;-1:-1:-1;;;;;130895:12:0;;;;;;;;;:::i;:::-;;;;;;;130909:5;130916:14;130850:15;:81::i;:::-;-1:-1:-1;130830:101:0;-1:-1:-1;130946:21:0;130830:101;130946:21;;:::i;:::-;;;130815:164;130810:3;;;;;:::i;:::-;;;;130773:206;;;-1:-1:-1;130998:8:0;;130307:707;-1:-1:-1;;;;;;;130307:707:0:o;44542:51::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;131208:107::-;16127:13;:11;:13::i;:::-;131278:16:::1;:29:::0;;-1:-1:-1;;;;;;131278:29:0::1;-1:-1:-1::0;;;;;131278:29:0;;;::::1;::::0;;;::::1;::::0;;131208:107::o;127807:562::-;127887:1;127878:6;:10;127870:44;;;;-1:-1:-1;;;127870:44:0;;32429:2:1;127870:44:0;;;32411:21:1;32468:2;32448:18;;;32441:30;-1:-1:-1;;;32487:18:1;;;32480:51;32548:18;;127870:44:0;32227:345:1;127870:44:0;127956:6;127946:7;;:16;;;;:::i;:::-;127933:9;:29;;127925:63;;;;-1:-1:-1;;;127925:63:0;;24164:2:1;127925:63:0;;;24146:21:1;24203:2;24183:18;;;24176:30;-1:-1:-1;;;24222:18:1;;;24215:51;24283:18;;127925:63:0;23962:345:1;127925:63:0;128030:9;;128020:6;128007:10;;:19;;;;:::i;:::-;:32;;127999:61;;;;-1:-1:-1;;;127999:61:0;;24514:2:1;127999:61:0;;;24496:21:1;24553:2;24533:18;;;24526:30;-1:-1:-1;;;24572:18:1;;;24565:46;24628:18;;127999:61:0;24312:340:1;127999:61:0;128098:16;;128090:76;;128072:12;;-1:-1:-1;;;;;128098:16:0;;128142:9;;128072:12;128090:76;128072:12;128090:76;128142:9;128098:16;128090:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;128071:95;;;128185:7;128177:16;;;;;;128211:8;128206:156;128229:6;128225:1;-1:-1:-1;;;;;128225:10:0;;128206:156;;;128270:10;;;;;;128257;128295:12;128270:10;128295:12;:::i;:::-;;;;;;128322:28;128332:10;128344:5;128322:9;:28::i;:::-;-1:-1:-1;128237:3:0;;;;:::i;:::-;;;;128206:156;;129536:763;129798:9;:16;129775:12;:19;:39;129767:103;;;;-1:-1:-1;;;129767:103:0;;;;;;;:::i;:::-;129902:9;129889;;:22;;129881:51;;;;-1:-1:-1;;;129881:51:0;;;;;;;:::i;:::-;129970:16;;130014:9;;129962:76;;129944:12;;-1:-1:-1;;;;;129970:16:0;;130014:9;129944:12;129962:76;129944:12;129962:76;130014:9;129970:16;129962:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129943:95;;;130057:7;130049:16;;;;;;130078:8;130097:195;130113:12;:19;130109:1;-1:-1:-1;;;;;130109:23:0;;130097:195;;;130154:126;130160:5;130167:12;130180:1;-1:-1:-1;;;;;130167:15:0;;;;;;;;;:::i;:::-;;;;;;;130184:10;130196:31;130214:9;130224:1;-1:-1:-1;;;;;130214:12:0;;;;;;;;;:::i;:::-;;;;;;;130196:17;:31::i;:::-;130229:14;130245:18;130265:14;130154:5;:126::i;:::-;130134:3;;;;:::i;:::-;;;;130097:195;;;129756:543;;129536:763;;;;;;;:::o;68619:1009::-;62533:21;:19;:21::i;:::-;68729:19;;::::1;::::0;;::::1;::::0;;;;68705:21:::1;68767:28:::0;;;:13:::1;:28:::0;;;;;;;:42:::1;;::::0;::::1;;68759:72;;;::::0;-1:-1:-1;;;68759:72:0;;32952:2:1;68759:72:0::1;::::0;::::1;32934:21:1::0;32991:2;32971:18;;;32964:30;-1:-1:-1;;;33010:18:1;;;33003:47;33067:18;;68759:72:0::1;32750:341:1::0;68759:72:0::1;68847:22;68884:8;68873:37;;;;;;;;;;;;:::i;:::-;68923:14;68952:28:::0;;;:13:::1;:28;::::0;;;;:39;;;69033:34;;::::1;::::0;68844:66;;-1:-1:-1;68923:14:0;;-1:-1:-1;68940:138:0::1;::::0;68952:39:::1;::::0;::::1;::::0;68993:38;;::::1;-1:-1:-1::0;;;;;68993:38:0::1;::::0;68844:66;68940:11:::1;:138::i;:::-;69109:28;::::0;;;:13:::1;:28;::::0;;;;:34:::1;;::::0;68923:155;;-1:-1:-1;69097:46:0;::::1;69089:100;;;::::0;-1:-1:-1;;;69089:100:0;;34852:2:1;69089:100:0::1;::::0;::::1;34834:21:1::0;34891:2;34871:18;;;34864:30;34930:34;34910:18;;;34903:62;-1:-1:-1;;;34981:18:1;;;34974:39;35030:19;;69089:100:0::1;34650:405:1::0;69089:100:0::1;69219:8;:15;69206:9;:28:::0;69202:419:::1;;69314:28;::::0;;;:13:::1;:28;::::0;;;;;69307:35;;-1:-1:-1;;;;;;69307:35:0;;;;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;69307:35:0::1;::::0;;69362:28;::::1;::::0;::::1;::::0;69328:13;4487:25:1;;4475:2;4460:18;;4341:177;69362:28:0::1;;;;;;;;69202:419;;;69499:110;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;69512:28:0;;;:13:::1;:28;::::0;;;;;;:39;;::::1;::::0;;::::1;69499:110:::0;;-1:-1:-1;;;;;69553:38:0;;;::::1;::::0;::::1;69499:110:::0;;::::1;::::0;;;;;;;;;69512:39;69499:110;;;;;;69468:28;;;;;;;;:141;;;;::::1;::::0;;::::1;-1:-1:-1::0;;;;;;69468:141:0;;;;;;::::1;::::0;;;;;;;::::1;::::0;;;;;;::::1;::::0;;;;;69553:38:::1;69468:141:::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;69468:141:0;;::::1;::::0;;;::::1;::::0;;69202:419:::1;68694:934;;;62577:20:::0;61971:1;63097:7;:22;62914:213;102692:104;102748:13;102781:7;102774:14;;;;;:::i;131113:87::-;16127:13;:11;:13::i;:::-;131176:9:::1;:16:::0;131113:87::o;71254:351::-;16127:13;:11;:13::i;:::-;71406:1:::1;71380:23;:27;71372:74;;;::::0;-1:-1:-1;;;71372:74:0;;35262:2:1;71372:74:0::1;::::0;::::1;35244:21:1::0;35301:2;35281:18;;;35274:30;35340:34;35320:18;;;35313:62;-1:-1:-1;;;35391:18:1;;;35384:32;35433:19;;71372:74:0::1;35060:398:1::0;71372:74:0::1;71457:35;::::0;::::1;;::::0;;;:22:::1;:35;::::0;;;;;;;;:61;;;71534:63;;35635:38:1;;;35689:18;;35682:34;;;71534:63:0::1;::::0;35608:18:1;71534:63:0::1;;;;;;;;71254:351:::0;;:::o;49525:330::-;49649:35;;;49629:17;49649:35;;;:19;:35;;;;;49629:55;;49604:12;;49629:17;49649:35;49629:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49703:4;:11;49718:1;49703:16;49695:58;;;;-1:-1:-1;;;49695:58:0;;35929:2:1;49695:58:0;;;35911:21:1;35968:2;35948:18;;;35941:30;36007:31;35987:18;;;35980:59;36056:18;;49695:58:0;35727:353:1;49695:58:0;49771:31;49782:1;49799:2;49785:4;:11;:16;;;;:::i;:::-;49771:4;;:31;:10;:31::i;:::-;49764:38;49525:330;-1:-1:-1;;;49525:330:0:o;104278:155::-;104373:52;15030:10;104406:8;104416;104373:18;:52::i;49236:281::-;16127:13;:11;:13::i;:::-;49408:14:::1;;49432:4;49391:47;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;49391:47:0;;::::1;::::0;;;;;;49353:35:::1;::::0;::::1;;::::0;;;:19:::1;49391:47;49353:35:::0;;;:85:::1;::::0;:35;:85:::1;:::i;:::-;;49454:55;49478:14;49494;;49454:55;;;;;;;;:::i;:::-;;;;;;;;49236:281:::0;;;:::o;128958:570::-;129246:9;129233;;:22;;129225:51;;;;-1:-1:-1;;;129225:51:0;;;;;;;:::i;:::-;129314:16;;129358:9;;129306:76;;129288:12;;-1:-1:-1;;;;;129314:16:0;;129358:9;129288:12;129306:76;129288:12;129306:76;129358:9;129314:16;129306:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129287:95;;;129401:7;129393:16;;;;;;129420:100;129426:5;129433:11;129446:10;129458:9;129469:14;129485:18;129505:14;129420:5;:100::i;105329:279::-;105460:41;15030:10;105493:7;105460:18;:41::i;:::-;105452:99;;;;-1:-1:-1;;;105452:99:0;;;;;;;:::i;:::-;105562:38;105576:4;105582:2;105586:7;105595:4;105562:13;:38::i;:::-;105329:279;;;;:::o;49863:136::-;16127:13;:11;:13::i;:::-;49933:8:::1;:20:::0;;-1:-1:-1;;;;;;49933:20:0::1;-1:-1:-1::0;;;;;49933:20:0;::::1;::::0;;::::1;::::0;;;49969:22:::1;::::0;3427:51:1;;;49969:22:0::1;::::0;3415:2:1;3400:18;49969:22:0::1;3281:203:1::0;126650:32:0;;;;;;;:::i;131703:522::-;131776:13;131824:16;131832:7;131824;:16::i;:::-;131802:113;;;;-1:-1:-1;;;131802:113:0;;38140:2:1;131802:113:0;;;38122:21:1;38179:2;38159:18;;;38152:30;38218:34;38198:18;;;38191:62;-1:-1:-1;;;38269:18:1;;;38262:45;38324:19;;131802:113:0;37938:411:1;131802:113:0;131926:28;131957:10;:8;:10::i;:::-;131926:41;;132025:1;132000:14;131994:28;:32;:223;;;;;;;;;;;;;;;;;132094:14;132127:18;:7;:16;:18::i;:::-;132164:13;132059:133;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;131978:239;131703:522;-1:-1:-1;;;131703:522:0:o;48216:204::-;16127:13;:11;:13::i;:::-;48350:62:::1;::::0;-1:-1:-1;;;48350:62:0;;-1:-1:-1;;;;;48350:10:0::1;:20;::::0;::::1;::::0;:62:::1;::::0;48371:8;;48381;;48391:11;;48404:7;;;;48350:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;70831:359:::0;16127:13;:11;:13::i;:::-;70986:1:::1;70959:24;:28;70951:76;;;::::0;-1:-1:-1;;;70951:76:0;;40320:2:1;70951:76:0::1;::::0;::::1;40302:21:1::0;40359:2;40339:18;;;40332:30;40398:34;40378:18;;;40371:62;-1:-1:-1;;;40449:18:1;;;40442:33;40492:19;;70951:76:0::1;40118:399:1::0;70951:76:0::1;71038:36;::::0;::::1;;::::0;;;:23:::1;:36;::::0;;;;;;;;:63;;;71117:65;;35635:38:1;;;35689:18;;35682:34;;;71117:65:0::1;::::0;35608:18:1;71117:65:0::1;35463:259:1::0;58577:767:0;58788:27;;;58766:19;58788:27;;;:14;:27;;;;;;:40;;;;58816:11;;;;58788:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58788:48:0;;;;;;;;;;;;-1:-1:-1;58788:48:0;58847:73;;;;-1:-1:-1;;;58847:73:0;;40724:2:1;58847:73:0;;;40706:21:1;40763:2;40743:18;;;40736:30;40802:34;40782:18;;;40775:62;-1:-1:-1;;;40853:18:1;;;40846:33;40896:19;;58847:73:0;40522:399:1;58847:73:0;58962:11;58949:8;;58939:19;;;;;;;:::i;:::-;;;;;;;;:34;58931:80;;;;-1:-1:-1;;;58931:80:0;;41128:2:1;58931:80:0;;;41110:21:1;41167:2;41147:18;;;41140:30;41206:34;41186:18;;;41179:62;-1:-1:-1;;;41257:18:1;;;41250:31;41298:19;;58931:80:0;40926:397:1;58931:80:0;59059:27;;;59118:1;59059:27;;;:14;:27;;;;;;:40;;;;59087:11;;;;59059:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59059:48:0;;;;;;;;;;;;:61;;;;59189:65;;;;;;;;;;;;;;;;;;;59211:11;;59224;;59189:65;;;;;;59224:11;59189:65;;59224:11;59189:65;;;;;;;;;-1:-1:-1;;59189:65:0;;;;;;;;;;;;;;;;;;;;;;59237:6;;-1:-1:-1;59189:65:0;-1:-1:-1;59245:8:0;;;;;;59189:65;;59245:8;;;;59189:65;;;;;;;;;-1:-1:-1;59189:21:0;;-1:-1:-1;;;59189:65:0:i;:::-;59270:66;59290:11;59303;;59316:6;59324:11;59270:66;;;;;;;;;;:::i;:::-;;;;;;;;58710:634;58577:767;;;;;;:::o;126617:26::-;;;;;;;:::i;131565:130::-;16127:13;:11;:13::i;:::-;131654::::1;:33;131670:17:::0;131654:13;:33:::1;:::i;50007:284::-:0;16127:13;:11;:13::i;:::-;50131:1:::1;50121:7;:11;50113:45;;;::::0;-1:-1:-1;;;50113:45:0;;42028:2:1;50113:45:0::1;::::0;::::1;42010:21:1::0;42067:2;42047:18;;;42040:30;-1:-1:-1;;;42086:18:1;;;42079:51;42147:18;;50113:45:0::1;41826:345:1::0;50113:45:0::1;50169:28;::::0;;::::1;;::::0;;;:15:::1;:28;::::0;;;;;;;:41;;::::1;::::0;;;;;;;;;;:51;;;50236:47;;42399:34:1;;;42449:18;;42442:43;;;;42501:18;;;42494:34;;;50236:47:0::1;::::0;42362:2:1;42347:18;50236:47:0::1;42176:358:1::0;49021:207:0;16127:13;:11;:13::i;:::-;49122:35:::1;::::0;::::1;;::::0;;;:19:::1;:35;::::0;;;;:43:::1;49160:5:::0;;49122:35;:43:::1;:::i;:::-;;49181:39;49198:14;49214:5;;49181:39;;;;;;;;:::i;131022:83::-:0;16127:13;:11;:13::i;:::-;131083:7:::1;:14:::0;131022:83::o;65242:388::-;65423:14;65439:11;65463:20;65497:10;65509:9;65486:33;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;65486:33:0;;;;;;;;;;-1:-1:-1;;;65537:85:0;;65486:33;-1:-1:-1;;;;;;65537:10:0;:23;;;;:85;;65561:11;;65582:4;;65486:33;;65598:7;;65607:14;;65537:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65530:92;;;;;65242:388;;;;;;;;:::o;17140:201::-;16127:13;:11;:13::i;:::-;-1:-1:-1;;;;;17229:22:0;::::1;17221:73;;;::::0;-1:-1:-1;;;17221:73:0;;44817:2:1;17221:73:0::1;::::0;::::1;44799:21:1::0;44856:2;44836:18;;;44829:30;44895:34;44875:18;;;44868:62;-1:-1:-1;;;44946:18:1;;;44939:36;44992:19;;17221:73:0::1;44615:402:1::0;17221:73:0::1;17305:28;17324:8;17305:18;:28::i;47943:211::-:0;48078:68;;-1:-1:-1;;;48078:68:0;;45259:6:1;45292:15;;;48078:68:0;;;45274:34:1;45344:15;;45324:18;;;45317:43;48127:4:0;45376:18:1;;;45369:60;45445:18;;;45438:34;;;48046:12:0;;48078:10;-1:-1:-1;;;;;48078:20:0;;;;45221:19:1;;48078:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;48078:68:0;;;;;;;;;;;;:::i;:::-;48071:75;;47943:211;;;;;;;:::o;57192:514::-;57342:12;57356:19;57379:153;57413:9;57424:3;57452:34;;;57488:11;57501;57514:6;57522:8;57429:102;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;57429:102:0;;;;;;;;;;;;;;-1:-1:-1;;;;;57429:102:0;-1:-1:-1;;;;;;57429:102:0;;;;;;;;;;57387:4;;57379:153;;:33;:153::i;:::-;57341:191;;;;57592:7;57587:112;;57616:71;57636:11;57649;57662:6;57670:8;57680:6;57616:19;:71::i;119138:224::-;119240:4;-1:-1:-1;;;;;;119264:50:0;;-1:-1:-1;;;119264:50:0;;:90;;;119318:36;119342:11;119318:23;:36::i;16406:132::-;16287:7;16314:6;-1:-1:-1;;;;;16314:6:0;15030:10;16470:23;16462:68;;;;-1:-1:-1;;;16462:68:0;;46587:2:1;16462:68:0;;;46569:21:1;;;46606:18;;;46599:30;46665:34;46645:18;;;46638:62;46717:18;;16462:68:0;46385:356:1;113598:135:0;113680:16;113688:7;113680;:16::i;:::-;113672:53;;;;-1:-1:-1;;;113672:53:0;;29317:2:1;113672:53:0;;;29299:21:1;29356:2;29336:18;;;29329:30;-1:-1:-1;;;29375:18:1;;;29368:54;29439:18;;113672:53:0;29115:348:1;112911:174:0;112986:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;112986:29:0;-1:-1:-1;;;;;112986:29:0;;;;;;;;:24;;113040:23;112986:24;113040:14;:23::i;:::-;-1:-1:-1;;;;;113031:46:0;;;;;;;;;;;112911:174;;:::o;108204:110::-;108280:26;108290:2;108294:7;108280:26;;;;;;;;;;;;:9;:26::i;107598:264::-;107691:4;107708:13;107724:23;107739:7;107724:14;:23::i;:::-;107708:39;;107777:5;-1:-1:-1;;;;;107766:16:0;:7;-1:-1:-1;;;;;107766:16:0;;:52;;;-1:-1:-1;;;;;;104625:25:0;;;104601:4;104625:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;107786:32;107766:87;;;;107846:7;-1:-1:-1;;;;;107822:31:0;:20;107834:7;107822:11;:20::i;:::-;-1:-1:-1;;;;;107822:31:0;;107758:96;107598:264;-1:-1:-1;;;;107598:264:0:o;111563:1229::-;111688:4;-1:-1:-1;;;;;111661:31:0;:23;111676:7;111661:14;:23::i;:::-;-1:-1:-1;;;;;111661:31:0;;111653:81;;;;-1:-1:-1;;;111653:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;111753:16:0;;111745:65;;;;-1:-1:-1;;;111745:65:0;;47354:2:1;111745:65:0;;;47336:21:1;47393:2;47373:18;;;47366:30;47432:34;47412:18;;;47405:62;-1:-1:-1;;;47483:18:1;;;47476:34;47527:19;;111745:65:0;47152:400:1;111745:65:0;111823:42;111844:4;111850:2;111854:7;111863:1;111823:20;:42::i;:::-;111995:4;-1:-1:-1;;;;;111968:31:0;:23;111983:7;111968:14;:23::i;:::-;-1:-1:-1;;;;;111968:31:0;;111960:81;;;;-1:-1:-1;;;111960:81:0;;;;;;;:::i;:::-;112113:24;;;;:15;:24;;;;;;;;112106:31;;-1:-1:-1;;;;;;112106:31:0;;;;;;-1:-1:-1;;;;;112589:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;112589:20:0;;;112624:13;;;;;;;;;:18;;112106:31;112624:18;;;112664:16;;;:7;:16;;;;;;:21;;;;;;;;;;112703:27;;112129:7;;112703:27;;;103623:346;103553:416;;:::o;71832:185::-;71944:13;;;71955:1;71944:13;;;;;;;;;71896;;71922:19;;71944:13;;;;;;;;;;;;-1:-1:-1;71944:13:0;71922:35;;71979:7;71968:5;71974:1;71968:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;72004:5;71832:185;-1:-1:-1;;71832:185:0:o;66353:1123::-;66628:1;66609:9;:16;:20;66601:52;;;;-1:-1:-1;;;66601:52:0;;47759:2:1;66601:52:0;;;47741:21:1;47798:2;47778:18;;;47771:30;-1:-1:-1;;;47817:18:1;;;47810:49;47876:18;;66601:52:0;47557:343:1;66601:52:0;66672:9;:16;66692:1;66672:21;:80;;;-1:-1:-1;66717:35:0;;;;;;;:22;:35;;;;;;66697:16;;:55;;66672:80;66664:127;;;;-1:-1:-1;;;66664:127:0;;48107:2:1;66664:127:0;;;48089:21:1;48146:2;48126:18;;;48119:30;48185:34;48165:18;;;48158:62;-1:-1:-1;;;48236:18:1;;;48229:32;48278:19;;66664:127:0;47905:398:1;66664:127:0;66809:6;66804:127;66825:9;:16;66821:1;:20;66804:127;;;66863:56;66874:5;66881:11;66894:10;66906:9;66916:1;66906:12;;;;;;;;:::i;:::-;;;;;;;66863:10;:56::i;:::-;66843:3;;;;:::i;:::-;;;;66804:127;;;;66943:20;66977:10;66989:9;66966:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;66943:56;;67013:14;67033:61;67050:11;67063:7;67072:5;67079:14;67033:16;:61::i;:::-;67012:82;;;67126:9;67113;:22;;67105:57;;;;-1:-1:-1;;;67105:57:0;;48510:2:1;67105:57:0;;;48492:21:1;48549:2;48529:18;;;48522:30;-1:-1:-1;;;48568:18:1;;;48561:52;48630:18;;67105:57:0;48308:346:1;67105:57:0;67278:16;;67239:36;;;;;;;:23;:36;;;;;;67175:120;;67190:11;;63568:1;;67223:14;;67239:55;;67278:16;67239:55;:::i;:::-;67175:14;:120::i;:::-;67306:92;67314:11;67327:7;67336:14;67352:18;67372:14;67388:9;67306:7;:92::i;:::-;67446:10;67414:54;;;;;;:::i;:::-;;;;;;;;67439:5;-1:-1:-1;;;;;67414:54:0;67426:11;67414:54;;;67458:9;67414:54;;;;;;:::i;:::-;;;;;;;;66559:917;;66353:1123;;;;;;;:::o;67484:1037::-;67726:27;67755:22;67792:8;67781:37;;;;;;;;;;;;:::i;:::-;67725:93;;;;67834:8;67843:1;67834:11;;;;;;;;:::i;:::-;;;;;;;67847:1;67834:14;67831:51;;67864:7;;;;67831:51;67983:2;67963:23;;67957:30;67892:17;68027:48;68039:11;67957:30;67892:17;68066:8;68027:11;:48::i;:::-;68010:65;;68102:8;:15;68090:9;:27;68086:347;;;68246:19;;;;;;;;;;68311:53;;;;;;;;;;;;;;-1:-1:-1;;;;;68311:53:0;;;;;;;;;;;;;;;68359:4;68311:53;;;;;;68222:21;68280:28;;;:13;:28;;;;;;;:84;;;;;;;;;;;-1:-1:-1;;;;;;68280:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68280:84:0;;;;;;;;;;68384:37;;;;;;68246:19;;68256:8;;68384:37;:::i;:::-;;;;;;;;68119:314;68086:347;68493:9;-1:-1:-1;;;;;68450:63:0;68480:11;68450:63;;;;;;:::i;:::-;;;;;;;;68467:11;68450:63;;;68504:8;68450:63;;;;;;:::i;:::-;;;;;;;;67672:849;;;;67484:1037;;;;:::o;17501:191::-;17575:16;17594:6;;-1:-1:-1;;;;;17611:17:0;;;-1:-1:-1;;;;;;17611:17:0;;;;;;17644:40;;17594:6;;;;;;;17644:40;;17575:16;17644:40;17564:128;17501:191;:::o;62613:293::-;62015:1;62747:7;;:19;62739:63;;;;-1:-1:-1;;;62739:63:0;;49713:2:1;62739:63:0;;;49695:21:1;49752:2;49732:18;;;49725:30;49791:33;49771:18;;;49764:61;49842:18;;62739:63:0;49511:355:1;62739:63:0;62015:1;62880:7;:18;62613:293::o;69827:574::-;69949:7;69977:11;69999:263;70010:9;:16;70006:1;:20;69999:263;;;70136:24;;70124:9;:36;70162:5;70120:47;70184:48;70194:11;70207:10;70219:9;70229:1;70219:12;;;;;;;;:::i;:::-;;;;;;;70184:9;:48::i;:::-;70247:3;;;;:::i;:::-;;;;69999:263;;34250:2779;34391:12;34445:7;34429:12;34445:7;34439:2;34429:12;:::i;:::-;:23;;34421:50;;;;-1:-1:-1;;;34421:50:0;;50073:2:1;34421:50:0;;;50055:21:1;50112:2;50092:18;;;50085:30;-1:-1:-1;;;50131:18:1;;;50124:44;50185:18;;34421:50:0;49871:338:1;34421:50:0;34507:16;34516:7;34507:6;:16;:::i;:::-;34490:6;:13;:33;;34482:63;;;;-1:-1:-1;;;34482:63:0;;50416:2:1;34482:63:0;;;50398:21:1;50455:2;50435:18;;;50428:30;-1:-1:-1;;;50474:18:1;;;50467:47;50531:18;;34482:63:0;50214:341:1;34482:63:0;34558:22;34624:15;;34653:1933;;;;36730:4;36724:11;36711:24;;36911:1;36900:9;36893:20;36961:4;36950:9;36946:20;36940:4;36933:34;34617:2365;;34653:1933;34830:4;34824:11;34811:24;;35467:2;35458:7;35454:16;35839:9;35832:17;35826:4;35822:28;35810:9;35799;35795:25;35791:60;35888:7;35884:2;35880:16;36137:6;36123:9;36116:17;36110:4;36106:28;36094:9;36086:6;36082:22;36078:57;36074:70;35916:426;36171:3;36167:2;36164:11;35916:426;;;36313:9;;36302:21;;36213:4;36205:13;;;;36246;35916:426;;;-1:-1:-1;;36362:26:0;;;36566:2;36549:11;-1:-1:-1;;36545:25:0;36539:4;36532:39;-1:-1:-1;34617:2365:0;-1:-1:-1;37012:9:0;34250:2779;-1:-1:-1;;;;34250:2779:0:o;113228:281::-;113349:8;-1:-1:-1;;;;;113340:17:0;:5;-1:-1:-1;;;;;113340:17:0;;113332:55;;;;-1:-1:-1;;;113332:55:0;;50762:2:1;113332:55:0;;;50744:21:1;50801:2;50781:18;;;50774:30;50840:27;50820:18;;;50813:55;50885:18;;113332:55:0;50560:349:1;113332:55:0;-1:-1:-1;;;;;113398:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;113398:46:0;;;;;;;;;;113460:41;;2099::1;;;113460::0;;2072:18:1;113460:41:0;;;;;;;113228:281;;;:::o;106489:270::-;106602:28;106612:4;106618:2;106622:7;106602:9;:28::i;:::-;106649:47;106672:4;106678:2;106682:7;106691:4;106649:22;:47::i;:::-;106641:110;;;;-1:-1:-1;;;106641:110:0;;;;;;;:::i;107303:128::-;107368:4;106966:16;;;:7;:16;;;;;;-1:-1:-1;;;;;106966:16:0;107392:31;;;107303:128::o;131323:113::-;131383:13;131416:12;131409:19;;;;;:::i;97966:716::-;98022:13;98073:14;98090:17;98101:5;98090:10;:17::i;:::-;98110:1;98090:21;98073:38;;98126:20;98160:6;-1:-1:-1;;;;;98149:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;98149:18:0;-1:-1:-1;98126:41:0;-1:-1:-1;98291:28:0;;;98307:2;98291:28;98348:288;-1:-1:-1;;98380:5:0;-1:-1:-1;;;98517:2:0;98506:14;;98501:30;98380:5;98488:44;98578:2;98569:11;;;-1:-1:-1;98599:21:0;98348:288;98599:21;-1:-1:-1;98657:6:0;97966:716;-1:-1:-1;;;97966:716:0:o;51915:1275::-;52077:4;52083:12;52145:15;52171:13;52195:24;52232:8;52222:19;;-1:-1:-1;;;;;52222:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52222:19:0;;52195:46;;52723:1;52697;52663:9;52657:16;52628:4;52617:9;52613:20;52582:1;52547:7;52521:4;52502:247;52490:259;;52814:16;52803:27;;52859:8;52850:7;52847:21;52844:78;;;52899:8;52888:19;;52844:78;53005:7;52992:11;52985:28;53123:7;53120:1;53113:4;53100:11;53096:22;53081:50;53160:8;;;;-1:-1:-1;51915:1275:0;-1:-1:-1;;;;;;51915:1275:0:o;57714:323::-;57938:8;57928:19;;;;;;57877:14;:27;57892:11;57877:27;;;;;;;;;;;;;;;57905:11;57877:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57877:48:0;;;;;;;;;:70;;;;57963:66;;;;57977:11;;57990;;57918:6;;58011:8;;58021:7;;57963:66;:::i;:::-;;;;;;;;57714:323;;;;;:::o;101595:305::-;101697:4;-1:-1:-1;;;;;;101734:40:0;;-1:-1:-1;;;101734:40:0;;:105;;-1:-1:-1;;;;;;;101791:48:0;;-1:-1:-1;;;101791:48:0;101734:105;:158;;;;101856:36;101880:11;101856:23;:36::i;108541:285::-;108636:18;108642:2;108646:7;108636:5;:18::i;:::-;108687:53;108718:1;108722:2;108726:7;108735:4;108687:22;:53::i;:::-;108665:153;;;;-1:-1:-1;;;108665:153:0;;;;;;;:::i;120268:895::-;120535:1;120523:9;:13;120519:202;;;120673:36;;-1:-1:-1;;;120673:36:0;;;;;;;;;;;120519:202;120751:12;-1:-1:-1;;;;;120780:18:0;;120776:187;;120815:40;120847:7;121983:10;:17;;121956:24;;;;:15;:24;;;;;:44;;;122011:24;;;;;;;;;;;;121879:164;120815:40;120776:187;;;120885:2;-1:-1:-1;;;;;120877:10:0;:4;-1:-1:-1;;;;;120877:10:0;;120873:90;;120904:47;120937:4;120943:7;120904:32;:47::i;:::-;-1:-1:-1;;;;;120977:16:0;;120973:183;;121010:45;121047:7;121010:36;:45::i;:::-;120973:183;;;121083:4;-1:-1:-1;;;;;121077:10:0;:2;-1:-1:-1;;;;;121077:10:0;;121073:83;;121104:40;121132:2;121136:7;121104:27;:40::i;125643:361::-;125760:42;15030:10;125779:12;14950:98;125760:42;125752:101;;;;-1:-1:-1;;;125752:101:0;;52391:2:1;125752:101:0;;;52373:21:1;52430:2;52410:18;;;52403:30;52469:34;52449:18;;;52442:62;-1:-1:-1;;;52520:18:1;;;52513:44;52574:19;;125752:101:0;52189:410:1;125752:101:0;125900:5;-1:-1:-1;;;;;125872:33:0;:24;125887:8;125872:14;:24::i;:::-;-1:-1:-1;;;;;125872:33:0;;125864:80;;;;-1:-1:-1;;;125864:80:0;;52806:2:1;125864:80:0;;;52788:21:1;52845:2;52825:18;;;52818:30;52884:34;52864:18;;;52857:62;-1:-1:-1;;;52935:18:1;;;52928:32;52977:19;;125864:80:0;52604:398:1;125864:80:0;125955:41;125965:5;125980:4;125987:8;125955:9;:41::i;46742:420::-;46878:21;46902:28;46915:14;46902:12;:28::i;:::-;46960;;;;46941:16;46960:28;;;:15;:28;;;;;;;;:35;;;;;;;;;;;;46878:52;;-1:-1:-1;46941:16:0;46960:47;;46998:9;;46960:47;:::i;:::-;46941:66;;47040:1;47026:11;:15;47018:54;;;;-1:-1:-1;;;47018:54:0;;53209:2:1;47018:54:0;;;53191:21:1;53248:2;53228:18;;;53221:30;53287:28;53267:18;;;53260:56;53333:18;;47018:54:0;53007:350:1;47018:54:0;47111:11;47091:16;:31;;47083:71;;;;-1:-1:-1;;;47083:71:0;;53564:2:1;47083:71:0;;;53546:21:1;53603:2;53583:18;;;53576:30;53642:29;53622:18;;;53615:57;53689:18;;47083:71:0;53362:351:1;46181:553:0;46404:32;;;46375:26;46404:32;;;:19;:32;;;;;46375:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46455:13;:20;46479:1;46455:25;46447:86;;;;-1:-1:-1;;;46447:86:0;;53920:2:1;46447:86:0;;;53902:21:1;53959:2;53939:18;;;53932:30;53998:34;53978:18;;;53971:62;-1:-1:-1;;;54049:18:1;;;54042:46;54105:19;;46447:86:0;53718:412:1;46447:86:0;46544:47;46562:11;46575:8;:15;46544:17;:47::i;:::-;46602:124;;-1:-1:-1;;;46602:124:0;;-1:-1:-1;;;;;46602:10:0;:15;;;;46625:10;;46602:124;;46637:11;;46650:13;;46665:8;;46675:14;;46691:18;;46711:14;;46602:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46364:370;46181:553;;;;;;:::o;126012:373::-;126120:17;126128:8;126120:7;:17::i;:::-;126119:18;:86;;;;126142:17;126150:8;126142:7;:17::i;:::-;:62;;;;-1:-1:-1;126199:4:0;126163:24;126178:8;126163:14;:24::i;:::-;-1:-1:-1;;;;;126163:41:0;;126142:62;126111:95;;;;;;126222:17;126230:8;126222:7;:17::i;:::-;126217:161;;126256:31;126266:10;126278:8;126256:9;:31::i;126217:161::-;126320:46;126338:4;126345:10;126357:8;126320:9;:46::i;114297:853::-;114451:4;-1:-1:-1;;;;;114472:13:0;;75445:19;:23;114468:675;;114508:71;;-1:-1:-1;;;114508:71:0;;-1:-1:-1;;;;;114508:36:0;;;;;:71;;15030:10;;114559:4;;114565:7;;114574:4;;114508:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;114508:71:0;;;;;;;;-1:-1:-1;;114508:71:0;;;;;;;;;;;;:::i;:::-;;;114504:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114749:6;:13;114766:1;114749:18;114745:328;;114792:60;;-1:-1:-1;;;114792:60:0;;;;;;;:::i;114745:328::-;115023:6;115017:13;115008:6;115004:2;115000:15;114993:38;114504:584;-1:-1:-1;;;;;;114630:51:0;-1:-1:-1;;;114630:51:0;;-1:-1:-1;114623:58:0;;114468:675;-1:-1:-1;115127:4:0;115120:11;;93710:948;93763:7;;-1:-1:-1;;;93841:17:0;;93837:106;;-1:-1:-1;;;93879:17:0;;;-1:-1:-1;93925:2:0;93915:12;93837:106;93970:8;93961:5;:17;93957:106;;94008:8;93999:17;;;-1:-1:-1;94045:2:0;94035:12;93957:106;94090:8;94081:5;:17;94077:106;;94128:8;94119:17;;;-1:-1:-1;94165:2:0;94155:12;94077:106;94210:7;94201:5;:16;94197:103;;94247:7;94238:16;;;-1:-1:-1;94283:1:0;94273:11;94197:103;94327:7;94318:5;:16;94314:103;;94364:7;94355:16;;;-1:-1:-1;94400:1:0;94390:11;94314:103;94444:7;94435:5;:16;94431:103;;94481:7;94472:16;;;-1:-1:-1;94517:1:0;94507:11;94431:103;94561:7;94552:5;:16;94548:68;;94599:1;94589:11;94644:6;93710:948;-1:-1:-1;;93710:948:0:o;64399:219::-;64501:4;-1:-1:-1;;;;;;64525:45:0;;-1:-1:-1;;;64525:45:0;;:85;;-1:-1:-1;;;;;;;;;;60227:40:0;;;64574:36;60118:157;109162:942;-1:-1:-1;;;;;109242:16:0;;109234:61;;;;-1:-1:-1;;;109234:61:0;;55930:2:1;109234:61:0;;;55912:21:1;;;55949:18;;;55942:30;56008:34;55988:18;;;55981:62;56060:18;;109234:61:0;55728:356:1;109234:61:0;109315:16;109323:7;109315;:16::i;:::-;109314:17;109306:58;;;;-1:-1:-1;;;109306:58:0;;56291:2:1;109306:58:0;;;56273:21:1;56330:2;56310:18;;;56303:30;56369;56349:18;;;56342:58;56417:18;;109306:58:0;56089:352:1;109306:58:0;109377:48;109406:1;109410:2;109414:7;109423:1;109377:20;:48::i;:::-;109524:16;109532:7;109524;:16::i;:::-;109523:17;109515:58;;;;-1:-1:-1;;;109515:58:0;;56291:2:1;109515:58:0;;;56273:21:1;56330:2;56310:18;;;56303:30;56369;56349:18;;;56342:58;56417:18;;109515:58:0;56089:352:1;109515:58:0;-1:-1:-1;;;;;109922:13:0;;;;;;:9;:13;;;;;;;;:18;;109939:1;109922:18;;;109964:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;109964:21:0;;;;;110003:33;109972:7;;109922:13;;110003:33;;109922:13;;110003:33;127432:367;;127401:398::o;122670:981::-;122936:22;122979:1;122961:15;122971:4;122961:9;:15::i;:::-;:19;;;;:::i;:::-;122991:18;123012:26;;;:17;:26;;;;;;122936:44;;-1:-1:-1;123145:28:0;;;123141:328;;-1:-1:-1;;;;;123212:18:0;;123190:19;123212:18;;;:12;:18;;;;;;;;:34;;;;;;;;;123263:30;;;;;;:44;;;123380:30;;:17;:30;;;;;:43;;;123141:328;-1:-1:-1;123565:26:0;;;;:17;:26;;;;;;;;123558:33;;;-1:-1:-1;;;;;123609:18:0;;;;;:12;:18;;;;;:34;;;;;;;123602:41;122670:981::o;123946:1079::-;124224:10;:17;124199:22;;124224:21;;124244:1;;124224:21;:::i;:::-;124256:18;124277:24;;;:15;:24;;;;;;124650:10;:26;;124199:46;;-1:-1:-1;124277:24:0;;124199:46;;124650:26;;;;;;:::i;:::-;;;;;;;;;124628:48;;124714:11;124689:10;124700;124689:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;124794:28;;;:15;:28;;;;;;;:41;;;124966:24;;;;;124959:31;125001:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;124017:1008;;;123946:1079;:::o;121464:214::-;121549:14;121566:13;121576:2;121566:9;:13::i;:::-;-1:-1:-1;;;;;121590:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;121635:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;121464:214:0:o;47170:271::-;47252:13;47311:2;47286:14;:21;:27;;47278:68;;;;-1:-1:-1;;;47278:68:0;;56780:2:1;47278:68:0;;;56762:21:1;56819:2;56799:18;;;56792:30;56858;56838:18;;;56831:58;56906:18;;47278:68:0;56578:352:1;47278:68:0;-1:-1:-1;47419:2:0;47399:23;47393:30;;47170:271::o;47449:389::-;47572:35;;;47548:21;47572:35;;;:22;:35;;;;;;;47622:21;;;47618:125;;-1:-1:-1;44475:5:0;47618:125;47777:16;47761:12;:32;;47753:77;;;;-1:-1:-1;;;47753:77:0;;57137:2:1;47753:77:0;;;57119:21:1;;;57156:18;;;57149:30;57215:34;57195:18;;;57188:62;57267:18;;47753:77:0;56935:356:1;14:159;81:20;;141:6;130:18;;120:29;;110:57;;163:1;160;153:12;110:57;14:159;;;:::o;178:347::-;229:8;239:6;293:3;286:4;278:6;274:17;270:27;260:55;;311:1;308;301:12;260:55;-1:-1:-1;334:20:1;;-1:-1:-1;;;;;366:30:1;;363:50;;;409:1;406;399:12;363:50;446:4;438:6;434:17;422:29;;498:3;491:4;482:6;474;470:19;466:30;463:39;460:59;;;515:1;512;505:12;460:59;178:347;;;;;:::o;530:171::-;597:20;;-1:-1:-1;;;;;646:30:1;;636:41;;626:69;;691:1;688;681:12;706:862;812:6;820;828;836;844;852;905:3;893:9;884:7;880:23;876:33;873:53;;;922:1;919;912:12;873:53;945:28;963:9;945:28;:::i;:::-;935:38;;1024:2;1013:9;1009:18;996:32;-1:-1:-1;;;;;1088:2:1;1080:6;1077:14;1074:34;;;1104:1;1101;1094:12;1074:34;1143:58;1193:7;1184:6;1173:9;1169:22;1143:58;:::i;:::-;1220:8;;-1:-1:-1;1117:84:1;-1:-1:-1;1117:84:1;;-1:-1:-1;1274:37:1;1307:2;1292:18;;1274:37;:::i;:::-;1264:47;;1364:2;1353:9;1349:18;1336:32;1320:48;;1393:2;1383:8;1380:16;1377:36;;;1409:1;1406;1399:12;1377:36;;1448:60;1500:7;1489:8;1478:9;1474:24;1448:60;:::i;:::-;706:862;;;;-1:-1:-1;706:862:1;;-1:-1:-1;706:862:1;;1527:8;;706:862;-1:-1:-1;;;706:862:1:o;1573:131::-;-1:-1:-1;;;;;;1647:32:1;;1637:43;;1627:71;;1694:1;1691;1684:12;1709:245;1767:6;1820:2;1808:9;1799:7;1795:23;1791:32;1788:52;;;1836:1;1833;1826:12;1788:52;1875:9;1862:23;1894:30;1918:5;1894:30;:::i;2151:250::-;2236:1;2246:113;2260:6;2257:1;2254:13;2246:113;;;2336:11;;;2330:18;2317:11;;;2310:39;2282:2;2275:10;2246:113;;;-1:-1:-1;;2393:1:1;2375:16;;2368:27;2151:250::o;2406:271::-;2448:3;2486:5;2480:12;2513:6;2508:3;2501:19;2529:76;2598:6;2591:4;2586:3;2582:14;2575:4;2568:5;2564:16;2529:76;:::i;:::-;2659:2;2638:15;-1:-1:-1;;2634:29:1;2625:39;;;;2666:4;2621:50;;2406:271;-1:-1:-1;;2406:271:1:o;2682:220::-;2831:2;2820:9;2813:21;2794:4;2851:45;2892:2;2881:9;2877:18;2869:6;2851:45;:::i;2907:184::-;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3057:28;3075:9;3057:28;:::i;3096:180::-;3155:6;3208:2;3196:9;3187:7;3183:23;3179:32;3176:52;;;3224:1;3221;3214:12;3176:52;-1:-1:-1;3247:23:1;;3096:180;-1:-1:-1;3096:180:1:o;3489:131::-;-1:-1:-1;;;;;3564:31:1;;3554:42;;3544:70;;3610:1;3607;3600:12;3625:134;3693:20;;3722:31;3693:20;3722:31;:::i;3764:315::-;3832:6;3840;3893:2;3881:9;3872:7;3868:23;3864:32;3861:52;;;3909:1;3906;3899:12;3861:52;3948:9;3935:23;3967:31;3992:5;3967:31;:::i;:::-;4017:5;4069:2;4054:18;;;;4041:32;;-1:-1:-1;;;3764:315:1:o;4084: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;5151:456::-;5228:6;5236;5244;5297:2;5285:9;5276:7;5272:23;5268:32;5265:52;;;5313:1;5310;5303:12;5265:52;5352:9;5339:23;5371:31;5396:5;5371:31;:::i;:::-;5421:5;-1:-1:-1;5478:2:1;5463:18;;5450:32;5491:33;5450:32;5491:33;:::i;:::-;5151:456;;5543:7;;-1:-1:-1;;;5597:2:1;5582:18;;;;5569:32;;5151:456::o;5612:127::-;5673:10;5668:3;5664:20;5661:1;5654:31;5704:4;5701:1;5694:15;5728:4;5725:1;5718:15;5744:275;5815:2;5809:9;5880:2;5861:13;;-1:-1:-1;;5857:27:1;5845:40;;-1:-1:-1;;;;;5900:34:1;;5936:22;;;5897:62;5894:88;;;5962:18;;:::i;:::-;5998:2;5991:22;5744:275;;-1:-1:-1;5744:275:1:o;6024:186::-;6072:4;-1:-1:-1;;;;;6097:6:1;6094:30;6091:56;;;6127:18;;:::i;:::-;-1:-1:-1;6193:2:1;6172:15;-1:-1:-1;;6168:29:1;6199:4;6164:40;;6024:186::o;6215:336::-;6279:5;6308:52;6324:35;6352:6;6324:35;:::i;:::-;6308:52;:::i;:::-;6299:61;;6383:6;6376:5;6369:21;6423:3;6414:6;6409:3;6405:16;6402:25;6399:45;;;6440:1;6437;6430:12;6399:45;6489:6;6484:3;6477:4;6470:5;6466:16;6453:43;6543:1;6536:4;6527:6;6520:5;6516:18;6512:29;6505:40;6215:336;;;;;:::o;6556:220::-;6598:5;6651:3;6644:4;6636:6;6632:17;6628:27;6618:55;;6669:1;6666;6659:12;6618:55;6691:79;6766:3;6757:6;6744:20;6737:4;6729:6;6725:17;6691:79;:::i;6781:160::-;6846:20;;6902:13;;6895:21;6885:32;;6875:60;;6931:1;6928;6921:12;6946:749;7055:6;7063;7071;7079;7087;7140:3;7128:9;7119:7;7115:23;7111:33;7108:53;;;7157:1;7154;7147:12;7108:53;7180:28;7198:9;7180:28;:::i;:::-;7170:38;;7259:2;7248:9;7244:18;7231:32;-1:-1:-1;;;;;7323:2:1;7315:6;7312:14;7309:34;;;7339:1;7336;7329:12;7309:34;7362:49;7403:7;7394:6;7383:9;7379:22;7362:49;:::i;:::-;7352:59;;7458:2;7447:9;7443:18;7430:32;7420:42;;7481:35;7512:2;7501:9;7497:18;7481:35;:::i;:::-;7471:45;;7569:3;7558:9;7554:19;7541:33;7525:49;;7599:2;7589:8;7586:16;7583:36;;;7615:1;7612;7605:12;7583:36;;7638:51;7681:7;7670:8;7659:9;7655:24;7638:51;:::i;:::-;7628:61;;;6946:749;;;;;;;;:::o;7953:481::-;8031:6;8039;8047;8100:2;8088:9;8079:7;8075:23;8071:32;8068:52;;;8116:1;8113;8106:12;8068:52;8139:28;8157:9;8139:28;:::i;:::-;8129:38;;8218:2;8207:9;8203:18;8190:32;-1:-1:-1;;;;;8237:6:1;8234:30;8231:50;;;8277:1;8274;8267:12;8231:50;8316:58;8366:7;8357:6;8346:9;8342:22;8316:58;:::i;:::-;7953:481;;8393:8;;-1:-1:-1;8290:84:1;;-1:-1:-1;;;;7953:481:1:o;8439:1108::-;8577:6;8585;8593;8601;8609;8617;8625;8678:3;8666:9;8657:7;8653:23;8649:33;8646:53;;;8695:1;8692;8685:12;8646:53;8734:9;8721:23;8753:31;8778:5;8753:31;:::i;:::-;8803:5;-1:-1:-1;8827:37:1;8860:2;8845:18;;8827:37;:::i;:::-;8817:47;;8915:2;8904:9;8900:18;8887:32;-1:-1:-1;;;;;8979:2:1;8971:6;8968:14;8965:34;;;8995:1;8992;8985:12;8965:34;9018:49;9059:7;9050:6;9039:9;9035:22;9018:49;:::i;:::-;9008:59;;9114:2;9103:9;9099:18;9086:32;9076:42;;9170:3;9159:9;9155:19;9142:33;9127:48;;9184:33;9209:7;9184:33;:::i;:::-;9236:7;;-1:-1:-1;9295:3:1;9280:19;;9267:33;;9309;9267;9309;:::i;:::-;9361:7;;-1:-1:-1;9421:3:1;9406:19;;9393:33;;9438:16;;;9435:36;;;9467:1;9464;9457:12;9435:36;;9490:51;9533:7;9522:8;9511:9;9507:24;9490:51;:::i;:::-;9480:61;;;8439:1108;;;;;;;;;;:::o;9552:450::-;9621:6;9674:2;9662:9;9653:7;9649:23;9645:32;9642:52;;;9690:1;9687;9680:12;9642:52;9730:9;9717:23;-1:-1:-1;;;;;9755:6:1;9752:30;9749:50;;;9795:1;9792;9785:12;9749:50;9818:22;;9871:4;9863:13;;9859:27;-1:-1:-1;9849:55:1;;9900:1;9897;9890:12;9849:55;9923:73;9988:7;9983:2;9970:16;9965:2;9961;9957:11;9923:73;:::i;10007:464::-;10091:6;10099;10107;10160:2;10148:9;10139:7;10135:23;10131:32;10128:52;;;10176:1;10173;10166:12;10128:52;10199:28;10217:9;10199:28;:::i;:::-;10189:38;;10278:2;10267:9;10263:18;10250:32;-1:-1:-1;;;;;10297:6:1;10294:30;10291:50;;;10337:1;10334;10327:12;10291:50;10360:49;10401:7;10392:6;10381:9;10377:22;10360:49;:::i;:::-;10350:59;;;10428:37;10461:2;10450:9;10446:18;10428:37;:::i;:::-;10418:47;;10007:464;;;;;:::o;10658:680::-;10758:6;10766;10774;10782;10835:3;10823:9;10814:7;10810:23;10806:33;10803:53;;;10852:1;10849;10842:12;10803:53;10875:28;10893:9;10875:28;:::i;:::-;10865:38;;10954:2;10943:9;10939:18;10926:32;-1:-1:-1;;;;;11018:2:1;11010:6;11007:14;11004:34;;;11034:1;11031;11024:12;11004:34;11057:49;11098:7;11089:6;11078:9;11074:22;11057:49;:::i;:::-;11047:59;;11125:35;11156:2;11145:9;11141:18;11125:35;:::i;:::-;11115:45;;11213:2;11202:9;11198:18;11185:32;11169:48;;11242:2;11232:8;11229:16;11226:36;;;11258:1;11255;11248:12;11226:36;;11281:51;11324:7;11313:8;11302:9;11298:24;11281:51;:::i;:::-;11271:61;;;10658:680;;;;;;;:::o;11343:247::-;11402:6;11455:2;11443:9;11434:7;11430:23;11426:32;11423:52;;;11471:1;11468;11461:12;11423:52;11510:9;11497:23;11529:31;11554:5;11529:31;:::i;11595:182::-;11654:4;-1:-1:-1;;;;;11679:6:1;11676:30;11673:56;;;11709:18;;:::i;:::-;-1:-1:-1;11754:1:1;11750:14;11766:4;11746:25;;11595:182::o;11782:665::-;11835:5;11888:3;11881:4;11873:6;11869:17;11865:27;11855:55;;11906:1;11903;11896:12;11855:55;11942:6;11929:20;11968:4;11992:59;12008:42;12047:2;12008:42;:::i;11992:59::-;12085:15;;;12171:1;12167:10;;;;12155:23;;12151:32;;;12116:12;;;;12195:15;;;12192:35;;;12223:1;12220;12213:12;12192:35;12259:2;12251:6;12247:15;12271:147;12287:6;12282:3;12279:15;12271:147;;;12353:22;12371:3;12353:22;:::i;:::-;12341:35;;12396:12;;;;12304;;12271:147;;;-1:-1:-1;12436:5:1;11782:665;-1:-1:-1;;;;;;11782:665:1:o;12452:661::-;12506:5;12559:3;12552:4;12544:6;12540:17;12536:27;12526:55;;12577:1;12574;12567:12;12526:55;12613:6;12600:20;12639:4;12663:59;12679:42;12718:2;12679:42;:::i;12663:59::-;12756:15;;;12842:1;12838:10;;;;12826:23;;12822:32;;;12787:12;;;;12866:15;;;12863:35;;;12894:1;12891;12884:12;12863:35;12930:2;12922:6;12918:15;12942:142;12958:6;12953:3;12950:15;12942:142;;;13024:17;;13012:30;;13062:12;;;;12975;;12942:142;;13118:791;13253:6;13261;13269;13322:2;13310:9;13301:7;13297:23;13293:32;13290:52;;;13338:1;13335;13328:12;13290:52;13378:9;13365:23;-1:-1:-1;;;;;13448:2:1;13440:6;13437:14;13434:34;;;13464:1;13461;13454:12;13434:34;13487:60;13539:7;13530:6;13519:9;13515:22;13487:60;:::i;:::-;13477:70;;13600:2;13589:9;13585:18;13572:32;13556:48;;13629:2;13619:8;13616:16;13613:36;;;13645:1;13642;13635:12;13613:36;13668:51;13711:7;13700:8;13689:9;13685:24;13668:51;:::i;:::-;13658:61;;13772:2;13761:9;13757:18;13744:32;13728:48;;13801:2;13791:8;13788:16;13785:36;;;13817:1;13814;13807:12;13785:36;;13840:63;13895:7;13884:8;13873:9;13869:24;13840:63;:::i;:::-;13830:73;;;13118:791;;;;;:::o;14137:1223::-;14325:6;14333;14341;14349;14357;14365;14373;14426:3;14414:9;14405:7;14401:23;14397:33;14394:53;;;14443:1;14440;14433:12;14394:53;14466:29;14485:9;14466:29;:::i;:::-;14456:39;;14546:2;14535:9;14531:18;14518:32;-1:-1:-1;;;;;14610:2:1;14602:6;14599:14;14596:34;;;14626:1;14623;14616:12;14596:34;14649:60;14701:7;14692:6;14681:9;14677:22;14649:60;:::i;:::-;14639:70;;14762:2;14751:9;14747:18;14734:32;14718:48;;14791:2;14781:8;14778:16;14775:36;;;14807:1;14804;14797:12;14775:36;14830:51;14873:7;14862:8;14851:9;14847:24;14830:51;:::i;:::-;14820:61;;14934:2;14923:9;14919:18;14906:32;14890:48;;14963:2;14953:8;14950:16;14947:36;;;14979:1;14976;14969:12;14947:36;15002:63;15057:7;15046:8;15035:9;15031:24;15002:63;:::i;:::-;14992:73;;15084:39;15118:3;15107:9;15103:19;15084:39;:::i;:::-;15074:49;;15142:39;15176:3;15165:9;15161:19;15142:39;:::i;:::-;15132:49;;15234:3;15223:9;15219:19;15206:33;15190:49;;15264:2;15254:8;15251:16;15248:36;;;15280:1;15277;15270:12;15365:256;15431:6;15439;15492:2;15480:9;15471:7;15467:23;15463:32;15460:52;;;15508:1;15505;15498:12;15460:52;15531:28;15549:9;15531:28;:::i;:::-;15521:38;;15578:37;15611:2;15600:9;15596:18;15578:37;:::i;:::-;15568:47;;15365:256;;;;;:::o;15626:320::-;15694:6;15747:2;15735:9;15726:7;15722:23;15718:32;15715:52;;;15763:1;15760;15753:12;15715:52;15803:9;15790:23;-1:-1:-1;;;;;15828:6:1;15825:30;15822:50;;;15868:1;15865;15858:12;15822:50;15891:49;15932:7;15923:6;15912:9;15908:22;15891:49;:::i;15951:315::-;16016:6;16024;16077:2;16065:9;16056:7;16052:23;16048:32;16045:52;;;16093:1;16090;16083:12;16045:52;16132:9;16119:23;16151:31;16176:5;16151:31;:::i;:::-;16201:5;-1:-1:-1;16225:35:1;16256:2;16241:18;;16225:35;:::i;16271:1199::-;16434:6;16442;16450;16458;16466;16474;16482;16535:3;16523:9;16514:7;16510:23;16506:33;16503:53;;;16552:1;16549;16542:12;16503:53;16591:9;16578:23;16610:31;16635:5;16610:31;:::i;:::-;16660:5;-1:-1:-1;16684:37:1;16717:2;16702:18;;16684:37;:::i;:::-;16674:47;;16772:2;16761:9;16757:18;16744:32;-1:-1:-1;;;;;16836:2:1;16828:6;16825:14;16822:34;;;16852:1;16849;16842:12;16822:34;16875:49;16916:7;16907:6;16896:9;16892:22;16875:49;:::i;:::-;16865:59;;16977:2;16966:9;16962:18;16949:32;16933:48;;17006:2;16996:8;16993:16;16990:36;;;17022:1;17019;17012:12;16990:36;17045:63;17100:7;17089:8;17078:9;17074:24;17045:63;:::i;:::-;17035:73;;17160:3;17149:9;17145:19;17132:33;17117:48;;17174:33;17199:7;17174:33;:::i;:::-;17226:7;17216:17;;17252:39;17286:3;17275:9;17271:19;17252:39;:::i;17902:665::-;17997:6;18005;18013;18021;18074:3;18062:9;18053:7;18049:23;18045:33;18042:53;;;18091:1;18088;18081:12;18042:53;18130:9;18117:23;18149:31;18174:5;18149:31;:::i;:::-;18199:5;-1:-1:-1;18256:2:1;18241:18;;18228:32;18269:33;18228:32;18269:33;:::i;:::-;18321:7;-1:-1:-1;18375:2:1;18360:18;;18347:32;;-1:-1:-1;18430:2:1;18415:18;;18402:32;-1:-1:-1;;;;;18446:30:1;;18443:50;;;18489:1;18486;18479:12;18443:50;18512:49;18553:7;18544:6;18533:9;18529:22;18512:49;:::i;18572:622::-;18667:6;18675;18683;18691;18699;18752:3;18740:9;18731:7;18727:23;18723:33;18720:53;;;18769:1;18766;18759:12;18720:53;18792:28;18810:9;18792:28;:::i;:::-;18782:38;;18839:37;18872:2;18861:9;18857:18;18839:37;:::i;:::-;18829:47;;18923:2;18912:9;18908:18;18895:32;18885:42;;18978:2;18967:9;18963:18;18950:32;-1:-1:-1;;;;;18997:6:1;18994:30;18991:50;;;19037:1;19034;19027:12;18991:50;19076:58;19126:7;19117:6;19106:9;19102:22;19076:58;:::i;:::-;18572:622;;;;-1:-1:-1;18572:622:1;;-1:-1:-1;19153:8:1;;19050:84;18572:622;-1:-1:-1;;;18572:622:1:o;19199:324::-;19274:6;19282;19290;19343:2;19331:9;19322:7;19318:23;19314:32;19311:52;;;19359:1;19356;19349:12;19311:52;19382:28;19400:9;19382:28;:::i;:::-;19372:38;;19429:37;19462:2;19451:9;19447:18;19429:37;:::i;:::-;19419:47;;19513:2;19502:9;19498:18;19485:32;19475:42;;19199:324;;;;;:::o;19528:388::-;19596:6;19604;19657:2;19645:9;19636:7;19632:23;19628:32;19625:52;;;19673:1;19670;19663:12;19625:52;19712:9;19699:23;19731:31;19756:5;19731:31;:::i;:::-;19781:5;-1:-1:-1;19838:2:1;19823:18;;19810:32;19851:33;19810:32;19851:33;:::i;:::-;19903:7;19893:17;;;19528:388;;;;;:::o;19921:907::-;20055:6;20063;20071;20079;20087;20140:3;20128:9;20119:7;20115:23;20111:33;20108:53;;;20157:1;20154;20147:12;20108:53;20180:28;20198:9;20180:28;:::i;:::-;20170:38;;20259:2;20248:9;20244:18;20231:32;-1:-1:-1;;;;;20323:2:1;20315:6;20312:14;20309:34;;;20339:1;20336;20329:12;20309:34;20362:49;20403:7;20394:6;20383:9;20379:22;20362:49;:::i;:::-;20352:59;;20464:2;20453:9;20449:18;20436:32;20420:48;;20493:2;20483:8;20480:16;20477:36;;;20509:1;20506;20499:12;20477:36;20532:63;20587:7;20576:8;20565:9;20561:24;20532:63;:::i;:::-;20522:73;;20614:35;20645:2;20634:9;20630:18;20614:35;:::i;20833:460::-;20917:6;20925;20933;20941;20994:3;20982:9;20973:7;20969:23;20965:33;20962:53;;;21011:1;21008;21001:12;20962:53;21034:28;21052:9;21034:28;:::i;:::-;21024:38;;21081:37;21114:2;21103:9;21099:18;21081:37;:::i;:::-;21071:47;;21168:2;21157:9;21153:18;21140:32;21181:31;21206:5;21181:31;:::i;:::-;20833:460;;;;-1:-1:-1;21231:5:1;;21283:2;21268:18;21255:32;;-1:-1:-1;;20833:460:1:o;21657:380::-;21736:1;21732:12;;;;21779;;;21800:61;;21854:4;21846:6;21842:17;21832:27;;21800:61;21907:2;21899:6;21896:14;21876:18;21873:38;21870:161;;21953:10;21948:3;21944:20;21941:1;21934:31;21988:4;21985:1;21978:15;22016:4;22013:1;22006:15;21870:161;;21657:380;;;:::o;22042:271::-;22225:6;22217;22212:3;22199:33;22181:3;22251:16;;22276:13;;;22251:16;22042:271;-1:-1:-1;22042:271:1:o;24867:127::-;24928:10;24923:3;24919:20;24916:1;24909:31;24959:4;24956:1;24949:15;24983:4;24980:1;24973:15;24999:135;25038:3;25059:17;;;25056:43;;25079:18;;:::i;:::-;-1:-1:-1;25126:1:1;25115:13;;24999:135::o;25139:409::-;25341:2;25323:21;;;25380:2;25360:18;;;25353:30;25419:34;25414:2;25399:18;;25392:62;-1:-1:-1;;;25485:2:1;25470:18;;25463:43;25538:3;25523:19;;25139:409::o;25832:266::-;25920:6;25915:3;25908:19;25972:6;25965:5;25958:4;25953:3;25949:14;25936:43;-1:-1:-1;26024:1:1;25999:16;;;26017:4;25995:27;;;25988:38;;;;26080:2;26059:15;;;-1:-1:-1;;26055:29:1;26046:39;;;26042:50;;25832:266::o;26103:326::-;26298:6;26290;26286:19;26275:9;26268:38;26342:2;26337;26326:9;26322:18;26315:30;26249:4;26362:61;26419:2;26408:9;26404:18;26396:6;26388;26362:61;:::i;26434:127::-;26495:10;26490:3;26486:20;26483:1;26476:31;26526:4;26523:1;26516:15;26550:4;26547:1;26540:15;26566:340;26768:2;26750:21;;;26807:2;26787:18;;;26780:30;-1:-1:-1;;;26841:2:1;26826:18;;26819:46;26897:2;26882:18;;26566:340::o;27037:545::-;27139:2;27134:3;27131:11;27128:448;;;27175:1;27200:5;27196:2;27189:17;27245:4;27241:2;27231:19;27315:2;27303:10;27299:19;27296:1;27292:27;27286:4;27282:38;27351:4;27339:10;27336:20;27333:47;;;-1:-1:-1;27374:4:1;27333:47;27429:2;27424:3;27420:12;27417:1;27413:20;27407:4;27403:31;27393:41;;27484:82;27502:2;27495:5;27492:13;27484:82;;;27547:17;;;27528:1;27517:13;27484:82;;27758:1352;27884:3;27878:10;-1:-1:-1;;;;;27903:6:1;27900:30;27897:56;;;27933:18;;:::i;:::-;27962:97;28052:6;28012:38;28044:4;28038:11;28012:38;:::i;:::-;28006:4;27962:97;:::i;:::-;28114:4;;28178:2;28167:14;;28195:1;28190:663;;;;28897:1;28914:6;28911:89;;;-1:-1:-1;28966:19:1;;;28960:26;28911:89;-1:-1:-1;;27715:1:1;27711:11;;;27707:24;27703:29;27693:40;27739:1;27735:11;;;27690:57;29013:81;;28160:944;;28190:663;26984:1;26977:14;;;27021:4;27008:18;;-1:-1:-1;;28226:20:1;;;28344:236;28358:7;28355:1;28352:14;28344:236;;;28447:19;;;28441:26;28426:42;;28539:27;;;;28507:1;28495:14;;;;28374:19;;28344:236;;;28348:3;28608:6;28599:7;28596:19;28593:201;;;28669:19;;;28663:26;-1:-1:-1;;28752:1:1;28748:14;;;28764:3;28744:24;28740:37;28736:42;28721:58;28706:74;;28593:201;-1:-1:-1;;;;;28840:1:1;28824:14;;;28820:22;28807:36;;-1:-1:-1;27758:1352:1:o;29875:642::-;30156:6;30144:19;;30126:38;;-1:-1:-1;;;;;30200:32:1;;30195:2;30180:18;;30173:60;30220:3;30264:2;30249:18;;30242:31;;;-1:-1:-1;;30296:46:1;;30322:19;;30314:6;30296:46;:::i;:::-;30392:6;30385:14;30378:22;30373:2;30362:9;30358:18;30351:50;30450:9;30442:6;30438:22;30432:3;30421:9;30417:19;30410:51;30478:33;30504:6;30496;30478:33;:::i;:::-;30470:41;29875:642;-1:-1:-1;;;;;;;;29875:642:1:o;30522:245::-;30601:6;30609;30662:2;30650:9;30641:7;30637:23;30633:32;30630:52;;;30678:1;30675;30668:12;30630:52;-1:-1:-1;;30701:16:1;;30757:2;30742:18;;;30736:25;30701:16;;30736:25;;-1:-1:-1;30522:245:1:o;31182:415::-;31384:2;31366:21;;;31423:2;31403:18;;;31396:30;31462:34;31457:2;31442:18;;31435:62;-1:-1:-1;;;31528:2:1;31513:18;;31506:49;31587:3;31572:19;;31182:415::o;31883:125::-;31948:9;;;31969:10;;;31966:36;;;31982:18;;:::i;32013:209::-;32051:3;-1:-1:-1;;;;;32132:2:1;32125:5;32121:14;32159:2;32150:7;32147:15;32144:41;;32165:18;;:::i;:::-;32214:1;32201:15;;32013:209;-1:-1:-1;;;32013:209:1:o;32577:168::-;32650:9;;;32681;;32698:15;;;32692:22;;32678:37;32668:71;;32719:18;;:::i;33096:441::-;33149:5;33202:3;33195:4;33187:6;33183:17;33179:27;33169:55;;33220:1;33217;33210:12;33169:55;33249:6;33243:13;33280:48;33296:31;33324:2;33296:31;:::i;33280:48::-;33353:2;33344:7;33337:19;33399:3;33392:4;33387:2;33379:6;33375:15;33371:26;33368:35;33365:55;;;33416:1;33413;33406:12;33365:55;33429:77;33503:2;33496:4;33487:7;33483:18;33476:4;33468:6;33464:17;33429:77;:::i;33542:1103::-;33655:6;33663;33716:2;33704:9;33695:7;33691:23;33687:32;33684:52;;;33732:1;33729;33722:12;33684:52;33765:9;33759:16;-1:-1:-1;;;;;33835:2:1;33827:6;33824:14;33821:34;;;33851:1;33848;33841:12;33821:34;33874:60;33926:7;33917:6;33906:9;33902:22;33874:60;:::i;:::-;33864:70;;33953:2;33943:12;;34001:2;33990:9;33986:18;33980:25;34030:2;34020:8;34017:16;34014:36;;;34046:1;34043;34036:12;34014:36;34069:24;;;-1:-1:-1;34124:4:1;34116:13;;34112:27;-1:-1:-1;34102:55:1;;34153:1;34150;34143:12;34102:55;34182:2;34176:9;34205:59;34221:42;34260:2;34221:42;:::i;34205:59::-;34298:15;;;34380:1;34376:10;;;;34368:19;;34364:28;;;34329:12;;;;34404:19;;;34401:39;;;34436:1;34433;34426:12;34401:39;34460:11;;;;34480:135;34496:6;34491:3;34488:15;34480:135;;;34562:10;;34550:23;;34513:12;;;;34593;;;;34480:135;;;34634:5;34624:15;;;;;;;33542:1103;;;;;:::o;36085:128::-;36152:9;;;36173:11;;;36170:37;;;36187:18;;:::i;36218:360::-;36429:6;36421;36416:3;36403:33;36499:2;36495:15;;;;-1:-1:-1;;36491:53:1;36455:16;;36480:65;;;36569:2;36561:11;;36218:360;-1:-1:-1;36218:360:1:o;38354:1256::-;38578:3;38616:6;38610:13;38642:4;38655:64;38712:6;38707:3;38702:2;38694:6;38690:15;38655:64;:::i;:::-;38782:13;;38741:16;;;;38804:68;38782:13;38741:16;38839:15;;;38804:68;:::i;:::-;38961:13;;38894:20;;;38934:1;;38999:36;38961:13;38999:36;:::i;:::-;39054:1;39071:18;;;39098:141;;;;39253:1;39248:337;;;;39064:521;;39098:141;-1:-1:-1;;39133:24:1;;39119:39;;39210:16;;39203:24;39189:39;;39178:51;;;-1:-1:-1;39098:141:1;;39248:337;39279:6;39276:1;39269:17;39327:2;39324:1;39314:16;39352:1;39366:169;39380:8;39377:1;39374:15;39366:169;;;39462:14;;39447:13;;;39440:37;39505:16;;;;39397:10;;39366:169;;;39370:3;;39566:8;39559:5;39555:20;39548:27;;39064:521;-1:-1:-1;39601:3:1;;38354:1256;-1:-1:-1;;;;;;;;;;38354:1256:1:o;39615:498::-;39815:4;39844:6;39889:2;39881:6;39877:15;39866:9;39859:34;39941:2;39933:6;39929:15;39924:2;39913:9;39909:18;39902:43;;39981:6;39976:2;39965:9;39961:18;39954:34;40024:3;40019:2;40008:9;40004:18;39997:31;40045:62;40102:3;40091:9;40087:19;40079:6;40071;40045:62;:::i;:::-;40037:70;39615:498;-1:-1:-1;;;;;;;39615:498:1:o;41328:493::-;41577:6;41569;41565:19;41554:9;41547:38;41621:3;41616:2;41605:9;41601:18;41594:31;41528:4;41642:62;41699:3;41688:9;41684:19;41676:6;41668;41642:62;:::i;:::-;-1:-1:-1;;;;;41740:31:1;;;;41735:2;41720:18;;41713:59;-1:-1:-1;41803:2:1;41788:18;41781:34;41634:70;41328:493;-1:-1:-1;;;41328:493:1:o;42539:1204::-;-1:-1:-1;;;;;42656:3:1;42653:27;42650:53;;;42683:18;;:::i;:::-;42712:94;42802:3;42762:38;42794:4;42788:11;42762:38;:::i;:::-;42756:4;42712:94;:::i;:::-;42832:1;42857:2;42852:3;42849:11;42874:1;42869:616;;;;43529:1;43546:3;43543:93;;;-1:-1:-1;43602:19:1;;;43589:33;43543:93;-1:-1:-1;;27715:1:1;27711:11;;;27707:24;27703:29;27693:40;27739:1;27735:11;;;27690:57;43649:78;;42842:895;;42869:616;26984:1;26977:14;;;27021:4;27008:18;;-1:-1:-1;;42905:17:1;;;43006:9;43028:229;43042:7;43039:1;43036:14;43028:229;;;43131:19;;;43118:33;43103:49;;43238:4;43223:20;;;;43191:1;43179:14;;;;43058:12;43028:229;;;43032:3;43285;43276:7;43273:16;43270:159;;;43409:1;43405:6;43399:3;43393;43390:1;43386:11;43382:21;43378:34;43374:39;43361:9;43356:3;43352:19;43339:33;43335:79;43327:6;43320:95;43270:159;;;43472:1;43466:3;43463:1;43459:11;43455:19;43449:4;43442:33;42842:895;;42539:1204;;;:::o;43748:435::-;43801:3;43839:5;43833:12;43866:6;43861:3;43854:19;43892:4;43921:2;43916:3;43912:12;43905:19;;43958:2;43951:5;43947:14;43979:1;43989:169;44003:6;44000:1;43997:13;43989:169;;;44064:13;;44052:26;;44098:12;;;;44133:15;;;;44025:1;44018:9;43989:169;;;-1:-1:-1;44174:3:1;;43748:435;-1:-1:-1;;;;;43748:435:1:o;44188:422::-;44413:2;44402:9;44395:21;44376:4;44439:45;44480:2;44469:9;44465:18;44457:6;44439:45;:::i;:::-;44532:9;44524:6;44520:22;44515:2;44504:9;44500:18;44493:50;44560:44;44597:6;44589;44560:44;:::i;:::-;44552:52;44188:422;-1:-1:-1;;;;;44188:422:1:o;45483:335::-;45562:6;45615:2;45603:9;45594:7;45590:23;45586:32;45583:52;;;45631:1;45628;45621:12;45583:52;45664:9;45658:16;-1:-1:-1;;;;;45689:6:1;45686:30;45683:50;;;45729:1;45726;45719:12;45683:50;45752:60;45804:7;45795:6;45784:9;45780:22;45752:60;:::i;45823:557::-;46080:6;46072;46068:19;46057:9;46050:38;46124:3;46119:2;46108:9;46104:18;46097:31;46031:4;46151:46;46192:3;46181:9;46177:19;46169:6;46151:46;:::i;:::-;-1:-1:-1;;;;;46237:6:1;46233:31;46228:2;46217:9;46213:18;46206:59;46313:9;46305:6;46301:22;46296:2;46285:9;46281:18;46274:50;46341:33;46367:6;46359;46341:33;:::i;46746:401::-;46948:2;46930:21;;;46987:2;46967:18;;;46960:30;47026:34;47021:2;47006:18;;46999:62;-1:-1:-1;;;47092:2:1;47077:18;;47070:35;47137:3;47122:19;;46746:401::o;48659:287::-;48788:3;48826:6;48820:13;48842:66;48901:6;48896:3;48889:4;48881:6;48877:17;48842:66;:::i;:::-;48924:16;;;;;48659:287;-1:-1:-1;;48659:287:1:o;48951:261::-;49130:2;49119:9;49112:21;49093:4;49150:56;49202:2;49191:9;49187:18;49179:6;49150:56;:::i;49217:289::-;49392:6;49381:9;49374:25;49435:2;49430;49419:9;49415:18;49408:30;49355:4;49455:45;49496:2;49485:9;49481:18;49473:6;49455:45;:::i;50914:414::-;51116:2;51098:21;;;51155:2;51135:18;;;51128:30;51194:34;51189:2;51174:18;;51167:62;-1:-1:-1;;;51260:2:1;51245:18;;51238:48;51318:3;51303:19;;50914:414::o;51465:719::-;51768:6;51760;51756:19;51745:9;51738:38;51812:3;51807:2;51796:9;51792:18;51785:31;51719:4;51839:46;51880:3;51869:9;51865:19;51857:6;51839:46;:::i;:::-;-1:-1:-1;;;;;51925:6:1;51921:31;51916:2;51905:9;51901:18;51894:59;52001:9;51993:6;51989:22;51984:2;51973:9;51969:18;51962:50;52035:33;52061:6;52053;52035:33;:::i;:::-;52021:47;;52117:9;52109:6;52105:22;52099:3;52088:9;52084:19;52077:51;52145:33;52171:6;52163;52145:33;:::i;54135:840::-;54484:6;54476;54472:19;54461:9;54454:38;54528:3;54523:2;54512:9;54508:18;54501:31;54435:4;54555:46;54596:3;54585:9;54581:19;54573:6;54555:46;:::i;:::-;54649:9;54641:6;54637:22;54632:2;54621:9;54617:18;54610:50;54683:33;54709:6;54701;54683:33;:::i;:::-;-1:-1:-1;;;;;54790:15:1;;;54785:2;54770:18;;54763:43;54843:15;;54837:3;54822:19;;54815:44;54896:22;;;54743:3;54875:19;;54868:51;54669:47;-1:-1:-1;54936:33:1;54669:47;54954:6;54936:33;:::i;:::-;54928:41;54135:840;-1:-1:-1;;;;;;;;;54135:840:1:o;54980:489::-;-1:-1:-1;;;;;55249:15:1;;;55231:34;;55301:15;;55296:2;55281:18;;55274:43;55348:2;55333:18;;55326:34;;;55396:3;55391:2;55376:18;;55369:31;;;55174:4;;55417:46;;55443:19;;55435:6;55417:46;:::i;:::-;55409:54;54980:489;-1:-1:-1;;;;;;54980:489:1:o;55474:249::-;55543:6;55596:2;55584:9;55575:7;55571:23;55567:32;55564:52;;;55612:1;55609;55602:12;55564:52;55644:9;55638:16;55663:30;55687:5;55663:30;:::i;56446:127::-;56507:10;56502:3;56498:20;56495:1;56488:31;56538:4;56535:1;56528:15;56562:4;56559:1;56552:15
Swarm Source
ipfs://a3603628701341dad3d02bf4edc4a64f6b29ae537065be7f75fb1bb5673776a2
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.