ERC-721
Overview
Max Total Supply
1,000 TIMMY
Holders
131
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Balance
154 TIMMYLoading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
ERC721Template
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity)
/** *Submitted for verification at ftmscan.com on 2022-02-05 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; // Sources flattened with hardhat v2.8.3 https://hardhat.org // File @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); } // File @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts v4.4.1 (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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, "Address: insufficient balance" ); (bool success, ) = recipient.call{value: amount}(""); require( success, "Address: unable to send value, recipient may have reverted" ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, "Address: low-level call with value failed" ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, "Address: insufficient balance for call" ); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall( target, data, "Address: low-level static call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require( oldAllowance >= value, "SafeERC20: decreased allowance below zero" ); uint256 newAllowance = oldAllowance - value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall( data, "SafeERC20: low-level call failed" ); if (returndata.length > 0) { // Return data is optional require( abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed" ); } } } // File @openzeppelin/contracts/utils/introspection/IERC165.sol // 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); } // File @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts v4.4.1 (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`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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 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; } // File @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts v4.4.1 (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 `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // 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); } // File @openzeppelin/contracts/utils/Context.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; } } // File @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } // File @openzeppelin/contracts/utils/introspection/ERC165.sol // 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; } } // File @openzeppelin/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/ERC721.sol) /** * @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 internal _name; // Token symbol string internal _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: balance query for the zero address" ); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require( owner != address(0), "ERC721: owner query for nonexistent token" ); 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) { require( _exists(tokenId), "ERC721Metadata: URI query for nonexistent token" ); 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 owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require( _exists(tokenId), "ERC721: approved query for nonexistent token" ); 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: transfer caller is not owner nor approved" ); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved" ); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require( _exists(tokenId), "ERC721: operator query for nonexistent token" ); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require( ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner" ); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {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 a {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 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 { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } // File @openzeppelin/contracts/interfaces/IERC165.sol // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) // File @openzeppelin/contracts/interfaces/IERC2981.sol // OpenZeppelin Contracts v4.4.1 (interfaces/IERC2981.sol) /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be payed in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); } // File @openzeppelin/contracts/token/common/ERC2981.sol // OpenZeppelin Contracts v4.4.0 (token/common/ERC2981.sol) /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require( feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice" ); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `tokenId` must be already minted. * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require( feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice" ); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // File @openzeppelin/contracts/token/ERC721/extensions/ERC721Royalty.sol // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Royalty.sol) /** * @dev Extension of ERC721 with the ERC2981 NFT Royalty Standard, a standardized way to retrieve royalty payment * information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC721Royalty is ERC2981, ERC721 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } /** * @dev See {ERC721-_burn}. This override additionally clears the royalty information for the token. */ function _burn(uint256 tokenId) internal virtual override { super._burn(tokenId); _resetTokenRoyalty(tokenId); } } // File @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol) /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol) /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require( index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds" ); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require( index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds" ); return _allTokens[index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File @openzeppelin/contracts/security/Pausable.sol // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool internal _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Modifier to make a function override the current pause state */ modifier overridePause() { bool wasPaused = paused(); if (wasPaused) { _unpause(); } _; if (wasPaused) { _pause(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File @openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Pausable.sol) /** * @dev ERC721 token with pausable token transfers, minting and burning. * * Useful for scenarios such as preventing trades until the end of an evaluation * period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ abstract contract ERC721Pausable is ERC721, Pausable { /** * @dev See {ERC721-_beforeTokenTransfer}. * * Requirements: * * - the contract must not be paused. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); require(!paused(), "ERC721Pausable: token transfer while paused"); } } // File @openzeppelin/contracts/access/IAccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged( bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole ); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted( bytes32 indexed role, address indexed account, address indexed sender ); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked( bytes32 indexed role, address indexed account, address indexed sender ); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File @openzeppelin/contracts/access/IAccessControlEnumerable.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); } // File @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol) /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require( account == _msgSender(), "AccessControl: can only renounce roles for self" ); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File @openzeppelin/contracts/utils/structs/EnumerableSet.sol // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } } // File @openzeppelin/contracts/access/AccessControlEnumerable.sol // OpenZeppelin Contracts v4.4.1 (access/AccessControlEnumerable.sol) /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } } // File @openzeppelin/contracts/proxy/Clones.sol // OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol) /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. * * _Available since v3.4._ */ library Clones { /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { assembly { let ptr := mload(0x40) mstore( ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000 ) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore( add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 ) instance := create(0, ptr, 0x37) } require(instance != address(0), "ERC1167: create failed"); } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { assembly { let ptr := mload(0x40) mstore( ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000 ) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore( add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 ) instance := create2(0, ptr, 0x37, salt) } require(instance != address(0), "ERC1167: create2 failed"); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { assembly { let ptr := mload(0x40) mstore( ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000 ) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore( add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000 ) mstore(add(ptr, 0x38), shl(0x60, deployer)) mstore(add(ptr, 0x4c), salt) mstore(add(ptr, 0x6c), keccak256(ptr, 0x37)) predicted := keccak256(add(ptr, 0x37), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress(address implementation, bytes32 salt) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } } // File @solidity-lib/contracts/libraries/FullMath.sol // taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1 // license is CC-BY-4.0 library FullMath { function fullMul(uint256 x, uint256 y) internal pure returns (uint256 l, uint256 h) { uint256 mm = mulmod(x, y, type(uint256).max); l = x * y; h = mm - l; if (mm < l) h -= 1; } function fullDiv( uint256 l, uint256 h, uint256 d ) private pure returns (uint256) { uint256 pow2 = d & (type(uint256).max * d); d /= pow2; l /= pow2; l += h * ((type(uint256).max * pow2) / pow2 + 1); uint256 r = 1; r *= 2 - d * r; return l * r; } function mulDiv( uint256 x, uint256 y, uint256 d ) internal pure returns (uint256) { (uint256 l, uint256 h) = fullMul(x, y); uint256 mm = mulmod(x, y, d); if (mm > l) h -= 1; l -= mm; if (h == 0) return l / d; require(h < d, "FullMath: FULLDIV_OVERFLOW"); return fullDiv(l, h, d); } } // File @solidity-lib/contracts/libraries/Babylonian.sol // computes square roots using the babylonian method // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method library Babylonian { // credit for this implementation goes to // https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol#L687 function sqrt(uint256 x) internal pure returns (uint256) { if (x == 0) return 0; // this block is equivalent to r = uint256(1) << (BitMath.mostSignificantBit(x) / 2); // however that code costs significantly more gas uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; // Seven iterations should be enough uint256 r1 = x / r; return (r < r1 ? r : r1); } } // File @solidity-lib/contracts/libraries/BitMath.sol library BitMath { // returns the 0 indexed position of the most significant bit of the input x // s.t. x >= 2**msb and x < 2**(msb+1) function mostSignificantBit(uint256 x) internal pure returns (uint8 r) { require(x > 0, "BitMath::mostSignificantBit: zero"); if (x >= 0x100000000000000000000000000000000) { x >>= 128; r += 128; } if (x >= 0x10000000000000000) { x >>= 64; r += 64; } if (x >= 0x100000000) { x >>= 32; r += 32; } if (x >= 0x10000) { x >>= 16; r += 16; } if (x >= 0x100) { x >>= 8; r += 8; } if (x >= 0x10) { x >>= 4; r += 4; } if (x >= 0x4) { x >>= 2; r += 2; } if (x >= 0x2) r += 1; } // returns the 0 indexed position of the least significant bit of the input x // s.t. (x & 2**lsb) != 0 and (x & (2**(lsb) - 1)) == 0) // i.e. the bit at the index is set and the mask of all lower bits is 0 function leastSignificantBit(uint256 x) internal pure returns (uint8 r) { require(x > 0, "BitMath::leastSignificantBit: zero"); r = 255; if (x & type(uint128).max > 0) { r -= 128; } else { x >>= 128; } if (x & type(uint64).max > 0) { r -= 64; } else { x >>= 64; } if (x & type(uint32).max > 0) { r -= 32; } else { x >>= 32; } if (x & type(uint16).max > 0) { r -= 16; } else { x >>= 16; } if (x & type(uint8).max > 0) { r -= 8; } else { x >>= 8; } if (x & 0xf > 0) { r -= 4; } else { x >>= 4; } if (x & 0x3 > 0) { r -= 2; } else { x >>= 2; } if (x & 0x1 > 0) r -= 1; } } // File @solidity-lib/contracts/libraries/FixedPoint.sol // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) library FixedPoint { // range: [0, 2**112 - 1] // resolution: 1 / 2**112 struct uq112x112 { uint224 _x; } // range: [0, 2**144 - 1] // resolution: 1 / 2**112 struct uq144x112 { uint256 _x; } uint8 public constant RESOLUTION = 112; uint256 public constant Q112 = 0x10000000000000000000000000000; // 2**112 uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000; // 2**224 uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits) // encode a uint112 as a UQ112x112 function encode(uint112 x) internal pure returns (uq112x112 memory) { return uq112x112(uint224(x) << RESOLUTION); } // encodes a uint144 as a UQ144x112 function encode144(uint144 x) internal pure returns (uq144x112 memory) { return uq144x112(uint256(x) << RESOLUTION); } // decode a UQ112x112 into a uint112 by truncating after the radix point function decode(uq112x112 memory self) internal pure returns (uint112) { return uint112(self._x >> RESOLUTION); } function decode112with18(uq112x112 memory self) internal pure returns (uint256) { return uint256(self._x) / 5192296858534827; } // decode a UQ144x112 into a uint144 by truncating after the radix point function decode144(uq144x112 memory self) internal pure returns (uint144) { return uint144(self._x >> RESOLUTION); } // multiply a UQ112x112 by a uint, returning a UQ144x112 // reverts on overflow function mul(uq112x112 memory self, uint256 y) internal pure returns (uq144x112 memory) { uint256 z = 0; require( y == 0 || (z = self._x * y) / y == self._x, "FixedPoint::mul: overflow" ); return uq144x112(z); } // multiply a UQ112x112 by an int and decode, returning an int // reverts on overflow function muli(uq112x112 memory self, int256 y) internal pure returns (int256) { uint256 z = FullMath.mulDiv(self._x, uint256(y < 0 ? -y : y), Q112); require(z < 2**255, "FixedPoint::muli: overflow"); return y < 0 ? -int256(z) : int256(z); } // multiply a UQ112x112 by a UQ112x112, returning a UQ112x112 // lossy function muluq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) { if (self._x == 0 || other._x == 0) { return uq112x112(0); } uint112 upper_self = uint112(self._x >> RESOLUTION); // * 2^0 uint112 lower_self = uint112(self._x & LOWER_MASK); // * 2^-112 uint112 upper_other = uint112(other._x >> RESOLUTION); // * 2^0 uint112 lower_other = uint112(other._x & LOWER_MASK); // * 2^-112 // partial products uint224 upper = uint224(upper_self) * upper_other; // * 2^0 uint224 lower = uint224(lower_self) * lower_other; // * 2^-224 uint224 uppers_lowero = uint224(upper_self) * lower_other; // * 2^-112 uint224 uppero_lowers = uint224(upper_other) * lower_self; // * 2^-112 // so the bit shift does not overflow require( upper <= type(uint112).max, "FixedPoint::muluq: upper overflow" ); // this cannot exceed 256 bits, all values are 224 bits uint256 sum = uint256(upper << RESOLUTION) + uppers_lowero + uppero_lowers + (lower >> RESOLUTION); // so the cast does not overflow require(sum <= type(uint224).max, "FixedPoint::muluq: sum overflow"); return uq112x112(uint224(sum)); } // divide a UQ112x112 by a UQ112x112, returning a UQ112x112 function divuq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) { require(other._x > 0, "FixedPoint::divuq: division by zero"); if (self._x == other._x) { return uq112x112(uint224(Q112)); } if (self._x <= type(uint144).max) { uint256 value = (uint256(self._x) << RESOLUTION) / other._x; require(value <= type(uint224).max, "FixedPoint::divuq: overflow"); return uq112x112(uint224(value)); } uint256 result = FullMath.mulDiv(Q112, self._x, other._x); require(result <= type(uint224).max, "FixedPoint::divuq: overflow"); return uq112x112(uint224(result)); } // returns a UQ112x112 which represents the ratio of the numerator to the denominator // can be lossy function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) { require(denominator > 0, "FixedPoint::fraction: division by zero"); if (numerator == 0) return FixedPoint.uq112x112(0); if (numerator <= type(uint144).max) { uint256 result = (numerator << RESOLUTION) / denominator; require( result <= type(uint224).max, "FixedPoint::fraction: overflow" ); return uq112x112(uint224(result)); } else { uint256 result = FullMath.mulDiv(numerator, Q112, denominator); require( result <= type(uint224).max, "FixedPoint::fraction: overflow" ); return uq112x112(uint224(result)); } } // take the reciprocal of a UQ112x112 // reverts on overflow // lossy function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) { require(self._x != 0, "FixedPoint::reciprocal: reciprocal of zero"); require(self._x != 1, "FixedPoint::reciprocal: overflow"); return uq112x112(uint224(Q224 / self._x)); } // square root of a UQ112x112 // lossy between 0/1 and 40 bits function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) { if (self._x <= type(uint144).max) { return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112))); } uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x); safeShiftBits -= safeShiftBits % 2; return uq112x112( uint224( Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2) ) ); } } // File contracts/interfaces/IUniswapV2TWAPOracle.sol interface IUniswapV2TWAPOracle { function PERIOD() external view returns (uint256); struct LastValue { address token0; address token1; uint256 price0Cumulative; uint256 price1Cumulative; uint32 blockTimestamp; FixedPoint.uq112x112 price0Average; FixedPoint.uq112x112 price1Average; } function consult( address pair, address token, uint256 amountIn ) external view returns (uint256 amountOut); function consultCurrent( address pair, address token, uint256 amountIn ) external view returns (uint256); function lastValue(address pair) external view returns (LastValue memory); function update(address pair) external; function updateAll() external; } // File contracts/interfaces/IPaymentSplitter.sol interface IPaymentSplitter { function initialize() external; function initialize(address[] memory payees, uint256[] memory shares_) external; function addPayee(address payee_, uint256 shares_) external; function count() external view returns (uint256); function totalShares() external view returns (uint256); function totalReleased() external view returns (uint256); function totalReleased(address token) external view returns (uint256); function shares(address account) external view returns (uint256); function released(address account) external view returns (uint256); function released(address token, address account) external view returns (uint256); function payee(uint256 index) external view returns (address); function pending(address account) external view returns (uint256); function pending(address token, address account) external view returns (uint256); function releaseAll() external; function releaseAll(address token) external; function release(address account) external; function release(address token, address account) external; } // File contracts/interfaces/IBlockTimeTracker.sol interface IBlockTimeTracker { function PRECISION() external view returns (uint8); function startBlock() external view returns (uint256); function startTimestamp() external view returns (uint256); function average() external view returns (uint256); function reset() external; } // File contracts/TimmyNFT/TimmyNFT.sol contract ERC721Template is ERC721Enumerable, ERC721Royalty, ERC721Pausable, AccessControlEnumerable { using SafeERC20 for IERC20; using Strings for uint256; using Address for address; using Clones for address; event RoyaltyDeployed( address indexed _contract, uint256 indexed _tokenId, address indexed recipient ); // fee settings uint256 public MINTING_FEE = 10 ether; uint256 public immutable MAX_TOKENS_PER_MINT = 10; uint96 public FTM_PREMIUM = 12500; address public immutable TRADING_PAIR = address(0xa8DE5367290Ed79658A9f9B9Ae1f633c355f1e1F); IERC20 public immutable PAYMENT_TOKEN = IERC20(0x6a31Aca4d2f7398F04d9B6ffae2D898d9A8e7938); IUniswapV2TWAPOracle public immutable ORACLE = IUniswapV2TWAPOracle(0x4B1B9F7ce4C40E9EdC1453F421Cf5CaeC384A085); // supply settings uint256 public immutable MAX_SUPPLY = 1000; // URI settings string private BASE_URI; string private URI_EXTENSION = ".json"; // Royalty settings address public PAYMENT_SPLITTER = address(0xaab3D332F05Af59A3Ada9Df9b7D3CED6EBe6b919); IPaymentSplitter public baseRoyaltyReceiver; mapping(address => IPaymentSplitter) public knownRoyaltyReceivers; mapping(uint256 => address) public tokenRoyaltyReceiver; address private immutable deployer; // Pauser role ID bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant SERVICE_ROLE = keccak256("SERVICE_ROLE"); // random seed for used in tokenURI generation uint256 private immutable RANDOM_SEED; // BlockTimeTracker for randomization IBlockTimeTracker private constant tracker = IBlockTimeTracker(0x706e05D2b47cc6B1fb615EE76DD3789d2329E22e); constructor() ERC721("TurtleTurtle.club: The Timmy Collection", "TIMMY") { _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(PAUSER_ROLE, _msgSender()); _setupRole(SERVICE_ROLE, _msgSender()); deployer = _msgSender(); baseRoyaltyReceiver = IPaymentSplitter(PAYMENT_SPLITTER.clone()); baseRoyaltyReceiver.initialize(); baseRoyaltyReceiver.addPayee(_msgSender(), 4); baseRoyaltyReceiver.addPayee(address(this), 6); RANDOM_SEED = uint256( keccak256( abi.encodePacked( _msgSender(), block.timestamp, block.number, address(this), tracker.average() ) ) ); emit RoyaltyDeployed(address(baseRoyaltyReceiver), 0, address(this)); _setDefaultRoyalty( address(baseRoyaltyReceiver), 500 // in basis points, 5% ); _pause(); } /****** ROYALTY SETTINGS ******/ function _constructRoyaltyReceiver(uint256 tokenId, address receiver) internal { if (address(knownRoyaltyReceivers[receiver]) == address(0)) { knownRoyaltyReceivers[receiver] = IPaymentSplitter( PAYMENT_SPLITTER.clone() ); knownRoyaltyReceivers[receiver].initialize(); knownRoyaltyReceivers[receiver].addPayee( address(baseRoyaltyReceiver), 1 ); knownRoyaltyReceivers[receiver].addPayee(receiver, 1); emit RoyaltyDeployed( address(knownRoyaltyReceivers[receiver]), tokenId, receiver ); } tokenRoyaltyReceiver[tokenId] = receiver; } /** * @dev Returns the pending royalties due to the original minter of the given token Id */ function pendingRoyalties(uint256 tokenId) public view returns (uint256) { if (!_exists(tokenId)) { return 0; } return knownRoyaltyReceivers[tokenRoyaltyReceiver[tokenId]].pending( tokenRoyaltyReceiver[tokenId] ); } /** * @dev Returns the pending royalties due to the original minter specified */ function pendingRoyalties(address minter) public view returns (uint256) { if (address(knownRoyaltyReceivers[minter]) == address(0)) { return 0; } return knownRoyaltyReceivers[minter].pending(minter); } /** * @dev Pays out any pending royalties due to the specified original minter */ function releaseRoyalties(address minter) public { require( address(knownRoyaltyReceivers[minter]) != address(0), "not an original minter" ); knownRoyaltyReceivers[minter].releaseAll(); } /****** MINT METHODS ******/ function getFTMQuote() public view returns (uint256) { uint256 ftmRate = ORACLE.consultCurrent( TRADING_PAIR, address(PAYMENT_TOKEN), MINTING_FEE ); return (ftmRate * FTM_PREMIUM) / 10000; } function getFTMQuoteSlippage() internal view returns (uint256 _min, uint256 _max) { uint256 mintFee = getFTMQuote(); _min = (mintFee * 9750) / 10000; // allows for -2.5% _max = (mintFee * 10250) / 10000; // allows for +2.5% } function updateOracle() internal { ORACLE.update(TRADING_PAIR); } /** * @dev standard mint function that regular users call while * paying the appropriate mint fee to mint the ERC721 */ function mint() public payable whenNotPaused returns (uint256) { (uint256 min, uint256 max) = getFTMQuoteSlippage(); require( msg.value >= min && msg.value <= max, "ERC20: caller did not supply correct amount of FTM" ); updateOracle(); return _mintERC721(_msgSender()); } /** * @dev standard mint function that regular users call while * paying the appropriate mint fee to mint a number of ERC721s */ function mintCount(uint8 count) public payable whenNotPaused returns (uint256[] memory) { require( count <= MAX_TOKENS_PER_MINT, "ERC721: must mint less than the maximum count per mint" ); (uint256 min, uint256 max) = getFTMQuoteSlippage(); require( msg.value >= min * count && msg.value <= max * count, "ERC20: caller did not supply correct amount of FTM" ); uint256[] memory tokenIds = new uint256[](count); for (uint256 i = 0; i < count; i++) { tokenIds[i] = _mintERC721(_msgSender()); } updateOracle(); return tokenIds; } /** * @dev standard mint function that regular users call while * paying the appropriate mint fee to mint a ERC721 */ function mintWithToken() public whenNotPaused returns (uint256) { require( PAYMENT_TOKEN.allowance(_msgSender(), address(this)) >= MINTING_FEE, "ERC20: caller must provide approval to spend token" ); PAYMENT_TOKEN.safeTransferFrom( _msgSender(), address(this), MINTING_FEE ); return _mintERC721(_msgSender()); } /** * @dev standard mint function that regular users call while * paying the appropriate mint fee to mint a number of ERC721s */ function mintWithTokenCount(uint256 count) public whenNotPaused returns (uint256[] memory) { require( count <= MAX_TOKENS_PER_MINT, "ERC721: must mint less than the maximum count per mint" ); uint256 totalMintingFee = MINTING_FEE * count; require( PAYMENT_TOKEN.allowance(_msgSender(), address(this)) >= totalMintingFee, "ERC20: caller must provide approval to spend token" ); PAYMENT_TOKEN.safeTransferFrom( _msgSender(), address(this), totalMintingFee ); uint256[] memory tokenIds = new uint256[](count); for (uint256 i = 0; i < count; i++) { tokenIds[i] = _mintERC721(_msgSender()); } return tokenIds; } /** * @dev mint process for admins only that allows overriding the * requirement for paying for the mint, allows minting while paused, * and mints the ERC721 directly to the wallet address specified */ function mintAdmin(address _to) public virtual onlyRole(DEFAULT_ADMIN_ROLE) overridePause returns (uint256) { return _mintERC721(_to); } /** * @dev mint process for admins only that allows overriding the * requirement for paying for the mint, allows minting while paused, * overrides the maximum number of ERC721s per mint, and mints the * ERC721 directly to the wallet address specified for the specified count */ function mintAdminCount(address _to, uint256 count) public onlyRole(DEFAULT_ADMIN_ROLE) overridePause returns (uint256[] memory) { uint256[] memory tokenIds = new uint256[](count); for (uint256 i = 0; i < count; i++) { tokenIds[i] = _mintERC721(_to); } return tokenIds; } /** * @dev internal mint method that sets up the actual ERC721 */ function _mintERC721(address _to) internal virtual returns (uint256) { uint256 supply = totalSupply(); require(supply + 1 <= MAX_SUPPLY, "mint completed"); uint256 tokenId = supply + 1; _constructRoyaltyReceiver(tokenId, _to); _safeMint(_to, tokenId); _setTokenRoyalty( tokenId, address(knownRoyaltyReceivers[tokenRoyaltyReceiver[tokenId]]), 500 ); // in basis points, 5% return tokenId; } /****** BASIC SETTING METHODS ******/ function pause() public onlyRole(PAUSER_ROLE) { _pause(); } function unpause() public onlyRole(PAUSER_ROLE) { _unpause(); } /****** FEE SETTING METHODS ******/ function setMintFee(uint256 _minting_fee) public onlyRole(DEFAULT_ADMIN_ROLE) { MINTING_FEE = _minting_fee; } function setFTMPremium(uint96 _ftm_premium) public onlyRole(DEFAULT_ADMIN_ROLE) { FTM_PREMIUM = _ftm_premium; } /****** URI SETTINGS ******/ /** * @dev updates the base URI for the token metadata to the provided URI */ function setBaseURI(string memory _base_uri) public onlyRole(DEFAULT_ADMIN_ROLE) { BASE_URI = _base_uri; } /** * @dev Generates a masked token URI so that people cannot guess what the next * NFT result will be */ function _generateTokenURI(uint256 tokenId) internal view returns (string memory) { return uint256( keccak256( abi.encodePacked(RANDOM_SEED.toString(), tokenId.toString()) ) ).toHexString(32); } /** * @dev returns the token masked URI for the given token Id */ function tokenMaskedURI(uint256 tokenId) public view onlyRole(SERVICE_ROLE) returns (string memory) { return _generateTokenURI(tokenId); } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _exists(tokenId), "ERC721Metadata: URI query for nonexistent token" ); return string( abi.encodePacked( BASE_URI, _generateTokenURI(tokenId), URI_EXTENSION ) ); } /****** WITHDRAW METHODS ******/ /** * @dev sends the full balance held by this contract to the caller */ function withdraw() public onlyRole(DEFAULT_ADMIN_ROLE) { require(address(this).balance != 0, "contract has no balance"); IPaymentSplitter splitter = IPaymentSplitter(PAYMENT_SPLITTER.clone()); splitter.initialize(); splitter.addPayee(_msgSender(), 90); if (_msgSender() != deployer) { splitter.addPayee(deployer, 10); } payable(address(splitter)).transfer(address(this).balance); splitter.releaseAll(); } /** * @dev sends the full balance of the given token held by this contract to the caller */ function withdraw(IERC20 token) public onlyRole(DEFAULT_ADMIN_ROLE) { require( token.balanceOf(address(this)) != 0, "contract has no balance of token" ); IPaymentSplitter splitter = IPaymentSplitter(PAYMENT_SPLITTER.clone()); splitter.initialize(); splitter.addPayee(_msgSender(), 90); if (_msgSender() != deployer) { splitter.addPayee(deployer, 10); } token.safeTransfer(address(splitter), token.balanceOf(address(this))); splitter.releaseAll(address(token)); } receive() external payable {} /****** INTERNAL OVERRIDES ******/ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) { super._beforeTokenTransfer(from, to, tokenId); } function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal override { if (tokenRoyaltyReceiver[tokenId] != address(0)) { knownRoyaltyReceivers[tokenRoyaltyReceiver[tokenId]].releaseAll(); } baseRoyaltyReceiver.releaseAll(); super._afterTokenTransfer(from, to, tokenId); } function _burn(uint256 tokenId) internal override(ERC721, ERC721Royalty) { super._burn(tokenId); } function supportsInterface(bytes4 interfaceId) public view virtual override( AccessControlEnumerable, ERC721, ERC721Enumerable, ERC721Royalty ) returns (bool) { return super.supportsInterface(interfaceId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_contract","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"RoyaltyDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FTM_PREMIUM","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_PER_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTING_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE","outputs":[{"internalType":"contract IUniswapV2TWAPOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_SPLITTER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_TOKEN","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SERVICE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRADING_PAIR","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"baseRoyaltyReceiver","outputs":[{"internalType":"contract IPaymentSplitter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFTMQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"knownRoyaltyReceivers","outputs":[{"internalType":"contract IPaymentSplitter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"mintAdmin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintAdminCount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"count","type":"uint8"}],"name":"mintCount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintWithToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintWithTokenCount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"pendingRoyalties","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"pendingRoyalties","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"releaseRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_base_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_ftm_premium","type":"uint96"}],"name":"setFTMPremium","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minting_fee","type":"uint256"}],"name":"setMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenMaskedURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"","type":"uint256"}],"name":"tokenRoyaltyReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
678ac7230489e80000600f55600a608052601080546001600160601b0319166130d417905573a8de5367290ed79658a9f9b9ae1f633c355f1e1f60a052736a31aca4d2f7398f04d9b6ffae2d898d9a8e793860c052734b1b9f7ce4c40e9edc1453f421cf5caec384a08560e0526103e8610100526101a0604052600561016081905264173539b7b760d91b6101809081526200009f916012919062000828565b50601380546001600160a01b03191673aab3d332f05af59a3ada9df9b7d3ced6ebe6b919179055348015620000d357600080fd5b506040518060600160405280602781526020016200690e602791396040518060400160405280600581526020016454494d4d5960d81b81525081600290805190602001906200012492919062000828565b5080516200013a90600390602084019062000828565b5050600c805460ff19169055506200015460003362000470565b620001807f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3362000470565b620001ac7fd8a7a79547af723ee3e12b59a480111268d8969c634e1a34a144d2c8b91d635b3362000470565b336001600160a01b0390811661012052601354620001d7911662000480602090811b62002df817901c565b601480546001600160a01b0319166001600160a01b039290921691821790556040805163204a7f0760e21b81529051638129fc1c9160048082019260009290919082900301818387803b1580156200022e57600080fd5b505af115801562000243573d6000803e3d6000fd5b50506014546001600160a01b031691506318f9b0239050336040516001600160e01b031960e084901b1681526001600160a01b039091166004828101919091526024820152604401600060405180830381600087803b158015620002a657600080fd5b505af1158015620002bb573d6000803e3d6000fd5b50506014546040516318f9b02360e01b8152306004820152600660248201526001600160a01b0390911692506318f9b0239150604401600060405180830381600087803b1580156200030c57600080fd5b505af115801562000321573d6000803e3d6000fd5b50505050620003356200046c60201b60201c565b42433073706e05d2b47cc6b1fb615ee76dd3789d2329e22e6001600160a01b031663b250717a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200038b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003b19190620008ce565b6040516001600160601b0319606096871b8116602083015260348201959095526054810193909352931b9091166074820152608881019190915260a80160408051601f198184030181529082905280516020909101206101405260145430916000916001600160a01b0316907fafa098bd63d0c6b0ddc6f328aba242372f2fe7974da70f45af0745ce98162f5c908390a46014546200045c906001600160a01b03166101f462000533565b6200046662000634565b62000925565b3390565b6200047c8282620006cf565b5050565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f09150506001600160a01b0381166200052e5760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c65640000000000000000000060448201526064015b60405180910390fd5b919050565b6127106001600160601b0382161115620005a35760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b606482015260840162000525565b6001600160a01b038216620005fb5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640162000525565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600055565b600c5460ff16156200067c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000525565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258620006b23390565b6040516001600160a01b03909116815260200160405180910390a1565b620006e682826200071260201b62002ed51760201c565b6000828152600e602090815260409091206200070d91839062002fc9620007b6821b17901c565b505050565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff166200047c576000828152600d602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620007723390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620007cd836001600160a01b038416620007d6565b90505b92915050565b60008181526001830160205260408120546200081f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620007d0565b506000620007d0565b8280546200083690620008e8565b90600052602060002090601f0160209004810192826200085a5760008555620008a5565b82601f106200087557805160ff1916838001178555620008a5565b82800160010185558215620008a5579182015b82811115620008a557825182559160200191906001019062000888565b50620008b3929150620008b7565b5090565b5b80821115620008b35760008155600101620008b8565b600060208284031215620008e157600080fd5b5051919050565b600181811c90821680620008fd57607f821691505b602082108114156200091f57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e051610100516101205161014051615f25620009e960003960006139b00152600081816119af01528181611a4301528181611ed20152611f660152600081816105ec01526131dc0152600081816106740152818161293101526134440152600081816108120152818161121201528181611377015281816128fc01528181612bcc0152612d18015260008181610a09015281816128d4015261341c0152600081816106200152818161231f0152612af40152615f256000f3fe60806040526004361061037a5760003560e01c80636352211e116101d1578063a5f0292b11610102578063d547741f116100a0578063e6226e5b1161006f578063e6226e5b14610b59578063e63ab1e914610b79578063e985e9c514610bad578063eddd0d9c14610c0357600080fd5b8063d547741f14610aee578063d642b4b114610b0e578063dfef140d14610b24578063e2fb107014610b3957600080fd5b8063c87b56dd116100dc578063c87b56dd14610a4b578063ca15c87314610a6b578063d0888d4414610a8b578063d4ba7d1214610aab57600080fd5b8063a5f0292b146109ca578063b608129c146109f7578063b88d4fde14610a2b57600080fd5b8063938f86af1161016f5780639a2fa9bb116101495780639a2fa9bb14610941578063a20e7d4714610961578063a217fddf14610995578063a22cb465146109aa57600080fd5b8063938f86af146108a757806395d89b41146108ea5780639991f016146108ff57600080fd5b80638456cb59116101ab5780638456cb59146107eb578063877c86fb146108005780639010d07c1461083457806391d148541461085457600080fd5b80636352211e1461079857806370a08231146107b8578063784b1ff0146107d857600080fd5b80632f745c59116102ab5780633f4ba83a116102495780634f6ccce7116102235780634f6ccce71461072057806351cff8d91461074057806355f804b3146107605780635c975abb1461078057600080fd5b80633f4ba83a146106cb57806342842e0e146106e0578063487458511461070057600080fd5b806336568abe1161028557806336568abe1461064257806338013f0214610662578063396478d3146106965780633ccfd60b146106b657600080fd5b80632f745c59146105ba57806332cb6b0c146105da5780633377cd661461060e57600080fd5b80631249c58b1161031857806323b872dd116102f257806323b872dd146104fe578063248a9ca31461051e5780632a55205a1461054e5780632f2ff15d1461059a57600080fd5b80631249c58b146104be578063171be8d0146104d457806318160ddd146104e957600080fd5b8063081812fc11610354578063081812fc1461042f578063095ea7b31461044f5780630e199130146104715780630e24d8e91461049e57600080fd5b806301ffc9a71461038657806305bab821146103bb57806306fdde031461040d57600080fd5b3661038157005b600080fd5b34801561039257600080fd5b506103a66103a136600461563a565b610c23565b60405190151581526020015b60405180910390f35b3480156103c757600080fd5b506014546103e89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103b2565b34801561041957600080fd5b50610422610c34565b6040516103b291906156cd565b34801561043b57600080fd5b506103e861044a3660046156e0565b610cc6565b34801561045b57600080fd5b5061046f61046a36600461571b565b610da5565b005b34801561047d57600080fd5b5061049161048c36600461571b565b610f32565b6040516103b29190615747565b3480156104aa57600080fd5b5061046f6104b936600461578b565b611000565b6104c661104b565b6040519081526020016103b2565b3480156104e057600080fd5b506104c6611183565b3480156104f557600080fd5b50600a546104c6565b34801561050a57600080fd5b5061046f6105193660046157b9565b6113ae565b34801561052a57600080fd5b506104c66105393660046156e0565b6000908152600d602052604090206001015490565b34801561055a57600080fd5b5061056e6105693660046157fa565b61144f565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152016103b2565b3480156105a657600080fd5b5061046f6105b536600461581c565b611546565b3480156105c657600080fd5b506104c66105d536600461571b565b61156b565b3480156105e657600080fd5b506104c67f000000000000000000000000000000000000000000000000000000000000000081565b34801561061a57600080fd5b506104c67f000000000000000000000000000000000000000000000000000000000000000081565b34801561064e57600080fd5b5061046f61065d36600461581c565b61163a565b34801561066e57600080fd5b506103e87f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a257600080fd5b5061046f6106b136600461584c565b6116ed565b3480156106c257600080fd5b5061046f61180c565b3480156106d757600080fd5b5061046f611b56565b3480156106ec57600080fd5b5061046f6106fb3660046157b9565b611b8b565b34801561070c57600080fd5b5061042261071b3660046156e0565b611ba6565b34801561072c57600080fd5b506104c661073b3660046156e0565b611be4565b34801561074c57600080fd5b5061046f61075b36600461584c565b611ca2565b34801561076c57600080fd5b5061046f61077b36600461592c565b61210a565b34801561078c57600080fd5b50600c5460ff166103a6565b3480156107a457600080fd5b506103e86107b33660046156e0565b612128565b3480156107c457600080fd5b506104c66107d336600461584c565b6121da565b6104916107e6366004615975565b6122a8565b3480156107f757600080fd5b5061046f612537565b34801561080c57600080fd5b506103e87f000000000000000000000000000000000000000000000000000000000000000081565b34801561084057600080fd5b506103e861084f3660046157fa565b612569565b34801561086057600080fd5b506103a661086f36600461581c565b6000918252600d6020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156108b357600080fd5b506103e86108c236600461584c565b60156020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156108f657600080fd5b50610422612588565b34801561090b57600080fd5b50601054610924906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff90911681526020016103b2565b34801561094d57600080fd5b506104c661095c36600461584c565b612597565b34801561096d57600080fd5b506104c67fd8a7a79547af723ee3e12b59a480111268d8969c634e1a34a144d2c8b91d635b81565b3480156109a157600080fd5b506104c6600081565b3480156109b657600080fd5b5061046f6109c53660046159a6565b612672565b3480156109d657600080fd5b506013546103e89073ffffffffffffffffffffffffffffffffffffffff1681565b348015610a0357600080fd5b506103e87f000000000000000000000000000000000000000000000000000000000000000081565b348015610a3757600080fd5b5061046f610a463660046159d4565b61267d565b348015610a5757600080fd5b50610422610a663660046156e0565b612725565b348015610a7757600080fd5b506104c6610a863660046156e0565b61280e565b348015610a9757600080fd5b506104c6610aa636600461584c565b612825565b348015610ab757600080fd5b506103e8610ac63660046156e0565b60166020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610afa57600080fd5b5061046f610b0936600461581c565b61286f565b348015610b1a57600080fd5b506104c6600f5481565b348015610b3057600080fd5b506104c6612894565b348015610b4557600080fd5b506104c6610b543660046156e0565b6129d0565b348015610b6557600080fd5b50610491610b743660046156e0565b612a7d565b348015610b8557600080fd5b506104c67f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b348015610bb957600080fd5b506103a6610bc8366004615a54565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610c0f57600080fd5b5061046f610c1e3660046156e0565b612de7565b6000610c2e82612feb565b92915050565b606060028054610c4390615a82565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6f90615a82565b8015610cbc5780601f10610c9157610100808354040283529160200191610cbc565b820191906000526020600020905b815481529060010190602001808311610c9f57829003601f168201915b5050505050905090565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16610d7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000610db082612128565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610e6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610d73565b3373ffffffffffffffffffffffffffffffffffffffff82161480610e975750610e978133610bc8565b610f23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610d73565b610f2d8383613041565b505050565b60606000610f3f816130e1565b6000610f4d600c5460ff1690565b90508015610f5d57610f5d6130eb565b60008467ffffffffffffffff811115610f7857610f78615869565b604051908082528060200260200182016040528015610fa1578160200160208202803683370190505b50905060005b85811015610fe757610fb8876131cc565b828281518110610fca57610fca615ad0565b602090810291909101015280610fdf81615b2e565b915050610fa7565b5092508015610ff857610ff86132d5565b505092915050565b600061100b816130e1565b50601080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b6000611059600c5460ff1690565b156110c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b6000806110cb613395565b915091508134101580156110df5750803411155b61116b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c657220646964206e6f7420737570706c7920636f7260448201527f7265637420616d6f756e74206f662046544d00000000000000000000000000006064820152608401610d73565b6111736133df565b61117c336131cc565b9250505090565b6000611191600c5460ff1690565b156111f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b600f5473ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663dd62ed3e336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb9190615b67565b1015611359576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c6572206d7573742070726f7669646520617070726f60448201527f76616c20746f207370656e6420746f6b656e00000000000000000000000000006064820152608401610d73565b6113a033600f5473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169190309061349c565b6113a9336131cc565b905090565b6113b83382613578565b611444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610d73565b610f2d8383836136e8565b600082815260016020908152604080832081518083019092525473ffffffffffffffffffffffffffffffffffffffff8116808352740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff1692820192909252829161150a57506040805180820190915260005473ffffffffffffffffffffffffffffffffffffffff811682527401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1660208201525b60208101516000906127109061152e906bffffffffffffffffffffffff1687615b80565b6115389190615bec565b915196919550909350505050565b6000828152600d6020526040902060010154611561816130e1565b610f2d8383613960565b6000611576836121da565b8210611604576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610d73565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b73ffffffffffffffffffffffffffffffffffffffff811633146116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610d73565b6116e98282613982565b5050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260409020541661177b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420616e206f726967696e616c206d696e746572000000000000000000006044820152606401610d73565b73ffffffffffffffffffffffffffffffffffffffff8082166000908152601560205260408082205481517f5be7fde80000000000000000000000000000000000000000000000000000000081529151931692635be7fde89260048084019391929182900301818387803b1580156117f157600080fd5b505af1158015611805573d6000803e3d6000fd5b5050505050565b6000611817816130e1565b4761187e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f636f6e747261637420686173206e6f2062616c616e63650000000000000000006044820152606401610d73565b6013546000906118a39073ffffffffffffffffffffffffffffffffffffffff16612df8565b90508073ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156118ed57600080fd5b505af1158015611901573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166318f9b0236119283390565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152605a6024820152604401600060405180830381600087803b15801561199557600080fd5b505af11580156119a9573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166119eb3390565b73ffffffffffffffffffffffffffffffffffffffff1614611aaf576040517f18f9b02300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152600a60248301528216906318f9b02390604401600060405180830381600087803b158015611a9657600080fd5b505af1158015611aaa573d6000803e3d6000fd5b505050505b60405173ffffffffffffffffffffffffffffffffffffffff8216904780156108fc02916000818181858888f19350505050158015611af1573d6000803e3d6000fd5b508073ffffffffffffffffffffffffffffffffffffffff16635be7fde86040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b3a57600080fd5b505af1158015611b4e573d6000803e3d6000fd5b505050505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a611b80816130e1565b611b886130eb565b50565b610f2d8383836040518060200160405280600081525061267d565b60607fd8a7a79547af723ee3e12b59a480111268d8969c634e1a34a144d2c8b91d635b611bd2816130e1565b611bdb836139a4565b91505b50919050565b6000611bef600a5490565b8210611c7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610d73565b600a8281548110611c9057611c90615ad0565b90600052602060002001549050919050565b6000611cad816130e1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611d17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3b9190615b67565b611da1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f636f6e747261637420686173206e6f2062616c616e6365206f6620746f6b656e6044820152606401610d73565b601354600090611dc69073ffffffffffffffffffffffffffffffffffffffff16612df8565b90508073ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e1057600080fd5b505af1158015611e24573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166318f9b023611e4b3390565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152605a6024820152604401600060405180830381600087803b158015611eb857600080fd5b505af1158015611ecc573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611f0e3390565b73ffffffffffffffffffffffffffffffffffffffff1614611fd2576040517f18f9b02300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152600a60248301528216906318f9b02390604401600060405180830381600087803b158015611fb957600080fd5b505af1158015611fcd573d6000803e3d6000fd5b505050505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015261208490829073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015612042573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120669190615b67565b73ffffffffffffffffffffffffffffffffffffffff86169190613a2a565b6040517f580fc80a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015282169063580fc80a90602401600060405180830381600087803b1580156120ed57600080fd5b505af1158015612101573d6000803e3d6000fd5b50505050505050565b6000612115816130e1565b8151610f2d906011906020850190615573565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610c2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610d73565b600073ffffffffffffffffffffffffffffffffffffffff821661227f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610d73565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205490565b60606122b6600c5460ff1690565b1561231d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b7f00000000000000000000000000000000000000000000000000000000000000008260ff1611156123d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4552433732313a206d757374206d696e74206c657373207468616e207468652060448201527f6d6178696d756d20636f756e7420706572206d696e74000000000000000000006064820152608401610d73565b6000806123db613395565b90925090506123ed60ff851683615b80565b3410158015612408575061240460ff851682615b80565b3411155b612494576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c657220646964206e6f7420737570706c7920636f7260448201527f7265637420616d6f756e74206f662046544d00000000000000000000000000006064820152608401610d73565b60008460ff1667ffffffffffffffff8111156124b2576124b2615869565b6040519080825280602002602001820160405280156124db578160200160208202803683370190505b50905060005b8560ff16811015612524576124f5336131cc565b82828151811061250757612507615ad0565b60209081029190910101528061251c81615b2e565b9150506124e1565b5061252d6133df565b925050505b919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a612561816130e1565b611b886132d5565b6000828152600e602052604081206125819083613a80565b9392505050565b606060038054610c4390615a82565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260408120549091166125cd57506000919050565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260156020526040908190205490517f5eebea20000000000000000000000000000000000000000000000000000000008152600481019290925290911690635eebea20906024015b602060405180830381865afa15801561264e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2e9190615b67565b6116e9338383613a8c565b6126873383613578565b612713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610d73565b61271f84848484613bba565b50505050565b60008181526004602052604090205460609073ffffffffffffffffffffffffffffffffffffffff166127d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006064820152608401610d73565b60116127e4836139a4565b60126040516020016127f893929190615cd1565b6040516020818303038152906040529050919050565b6000818152600e60205260408120610c2e90613c5d565b600080612831816130e1565b600061283f600c5460ff1690565b9050801561284f5761284f6130eb565b612858846131cc565b92508015612868576128686132d5565b5050919050565b6000828152600d602052604090206001015461288a816130e1565b610f2d8383613982565b600f546040517ffd5cb07d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152604482019290925260009182917f00000000000000000000000000000000000000000000000000000000000000009091169063fd5cb07d90606401602060405180830381865afa15801561297a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299e9190615b67565b601054909150612710906129c0906bffffffffffffffffffffffff1683615b80565b6129ca9190615bec565b91505090565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16612a0157506000919050565b60008281526016602081815260408084205473ffffffffffffffffffffffffffffffffffffffff90811680865260158452828620549588905293909252517f5eebea2000000000000000000000000000000000000000000000000000000000815260048101929092529190911690635eebea2090602401612631565b6060612a8b600c5460ff1690565b15612af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b7f0000000000000000000000000000000000000000000000000000000000000000821115612ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4552433732313a206d757374206d696e74206c657373207468616e207468652060448201527f6d6178696d756d20636f756e7420706572206d696e74000000000000000000006064820152608401610d73565b600082600f54612bb29190615b80565b90508073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663dd62ed3e336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015612c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c859190615b67565b1015612d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c6572206d7573742070726f7669646520617070726f60448201527f76616c20746f207370656e6420746f6b656e00000000000000000000000000006064820152608401610d73565b612d557f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633308461349c565b60008367ffffffffffffffff811115612d7057612d70615869565b604051908082528060200260200182016040528015612d99578160200160208202803683370190505b50905060005b84811015612ddf57612db0336131cc565b828281518110612dc257612dc2615ad0565b602090810291909101015280612dd781615b2e565b915050612d9f565b509392505050565b6000612df2816130e1565b50600f55565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f091505073ffffffffffffffffffffffffffffffffffffffff8116612532576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f455243313136373a20637265617465206661696c6564000000000000000000006044820152606401610d73565b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166116e9576000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612f6b3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006125818373ffffffffffffffffffffffffffffffffffffffff8416613c67565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f5a05180f000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82613cb6565b600081815260066020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061309b82612128565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611b888133613d0c565b600c5460ff16613157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610d73565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000806131d8600a5490565b90507f0000000000000000000000000000000000000000000000000000000000000000613206826001615cf9565b111561326e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6d696e7420636f6d706c657465640000000000000000000000000000000000006044820152606401610d73565b600061327b826001615cf9565b90506132878185613dde565b61329184826140c6565b60008181526016602090815260408083205473ffffffffffffffffffffffffffffffffffffffff9081168452601590925290912054612581918391166101f46140e0565b600c5460ff1615613342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586131a23390565b60008060006133a2612894565b90506127106133b382612616615b80565b6133bd9190615bec565b92506127106133ce8261280a615b80565b6133d89190615bec565b9150509091565b6040517f1c1b877200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527f00000000000000000000000000000000000000000000000000000000000000001690631c1b877290602401600060405180830381600087803b15801561348857600080fd5b505af115801561271f573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261271f9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261426a565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16613629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610d73565b600061363483612128565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806136a357508373ffffffffffffffffffffffffffffffffffffffff1661368b84610cc6565b73ffffffffffffffffffffffffffffffffffffffff16145b806136e0575073ffffffffffffffffffffffffffffffffffffffff80821660009081526007602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661370882612128565b73ffffffffffffffffffffffffffffffffffffffff16146137ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff821661384d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610d73565b613858838383614376565b613863600082613041565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600560205260408120805460019290613899908490615d11565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604081208054600192906138d4908490615cf9565b909155505060008181526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4610f2d838383614381565b61396a8282612ed5565b6000828152600e60205260409020610f2d9082612fc9565b61398c82826144ae565b6000828152600e60205260409020610f2d9082614569565b6060610c2e60206139d47f000000000000000000000000000000000000000000000000000000000000000061458b565b6139dd8561458b565b6040516020016139ee929190615d28565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120906146bd565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f2d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016134f6565b60006125818383614900565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613b22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d73565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526007602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b613bc58484846136e8565b613bd18484848461492a565b61271f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b6000610c2e825490565b6000818152600183016020526040812054613cae57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c2e565b506000610c2e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82614b1a565b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166116e957613d648173ffffffffffffffffffffffffffffffffffffffff1660146146bd565b613d6f8360206146bd565b604051602001613d80929190615d57565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610d73916004016156cd565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260409020541661407357601354613e2c9073ffffffffffffffffffffffffffffffffffffffff16612df8565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526015602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169490931693841790925581517f8129fc1c0000000000000000000000000000000000000000000000000000000081529151638129fc1c92600480820193929182900301818387803b158015613ecb57600080fd5b505af1158015613edf573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff818116600090815260156020526040908190205460145491517f18f9b023000000000000000000000000000000000000000000000000000000008152918316600483015260016024830152909116906318f9b02390604401600060405180830381600087803b158015613f6a57600080fd5b505af1158015613f7e573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff818116600081815260156020526040908190205490517f18f9b023000000000000000000000000000000000000000000000000000000008152600481019290925260016024830152909116906318f9b02390604401600060405180830381600087803b15801561400657600080fd5b505af115801561401a573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff808316600081815260156020526040808220549051929450869316917fafa098bd63d0c6b0ddc6f328aba242372f2fe7974da70f45af0745ce98162f5c9190a45b60009182526016602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6116e9828260405180602001604052806000815250614b25565b6127106bffffffffffffffffffffffff82161115614180576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff82166141fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610d73565b60408051808201825273ffffffffffffffffffffffffffffffffffffffff93841681526bffffffffffffffffffffffff9283166020808301918252600096875260019052919094209351905190911674010000000000000000000000000000000000000000029116179055565b60006142cc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614bc89092919063ffffffff16565b805190915015610f2d57808060200190518101906142ea9190615dd8565b610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d73565b610f2d838383614bd7565b60008181526016602052604090205473ffffffffffffffffffffffffffffffffffffffff16156144445760008181526016602090815260408083205473ffffffffffffffffffffffffffffffffffffffff908116845260159092528083205481517f5be7fde80000000000000000000000000000000000000000000000000000000081529151921692635be7fde89260048084019382900301818387803b15801561442b57600080fd5b505af115801561443f573d6000803e3d6000fd5b505050505b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635be7fde86040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156120ed57600080fd5b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156116e9576000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006125818373ffffffffffffffffffffffffffffffffffffffff8416614c75565b6060816145cb57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156145f557806145df81615b2e565b91506145ee9050600a83615bec565b91506145cf565b60008167ffffffffffffffff81111561461057614610615869565b6040519080825280601f01601f19166020018201604052801561463a576020820181803683370190505b5090505b841561252d5761464f600183615d11565b915061465c600a86615df5565b614667906030615cf9565b60f81b81838151811061467c5761467c615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506146b6600a86615bec565b945061463e565b606060006146cc836002615b80565b6146d7906002615cf9565b67ffffffffffffffff8111156146ef576146ef615869565b6040519080825280601f01601f191660200182016040528015614719576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061475057614750615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106147b3576147b3615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006147ef846002615b80565b6147fa906001615cf9565b90505b6001811115614897577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061483b5761483b615ad0565b1a60f81b82828151811061485157614851615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361489081615e09565b90506147fd565b508315612581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d73565b600082600001828154811061491757614917615ad0565b9060005260206000200154905092915050565b600073ffffffffffffffffffffffffffffffffffffffff84163b15614b0f576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a02906149a1903390899088908890600401615e3e565b6020604051808303816000875af19250505080156149fa575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526149f791810190615e87565b60015b614ac4573d808015614a28576040519150601f19603f3d011682016040523d82523d6000602084013e614a2d565b606091505b508051614abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506136e0565b506001949350505050565b6000610c2e82614d68565b614b2f8383614dbe565b614b3c600084848461492a565b610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b60606136e08484600085614f94565b614be283838361512a565b600c5460ff1615610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201527f68696c65207061757365640000000000000000000000000000000000000000006064820152608401610d73565b60008181526001830160205260408120548015614d5e576000614c99600183615d11565b8554909150600090614cad90600190615d11565b9050818114614d12576000866000018281548110614ccd57614ccd615ad0565b9060005260206000200154905080876000018481548110614cf057614cf0615ad0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614d2357614d23615ea4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610c2e565b6000915050610c2e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82615230565b73ffffffffffffffffffffffffffffffffffffffff8216614e3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d73565b60008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1615614ec7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d73565b614ed360008383614376565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600560205260408120805460019290614f09908490615cf9565b909155505060008181526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46116e960008383614381565b606082471015615026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff85163b6150a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d73565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516150cd9190615ed3565b60006040518083038185875af1925050503d806000811461510a576040519150601f19603f3d011682016040523d82523d6000602084013e61510f565b606091505b509150915061511f8282866152d2565b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166151925761518d81600a80546000838152600b60205260408120829055600182018355919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80155565b6151cf565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146151cf576151cf8382615325565b73ffffffffffffffffffffffffffffffffffffffff82166151f357610f2d816153dc565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610f2d57610f2d828261548b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806152c357507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610c2e5750610c2e826154dc565b606083156152e1575081612581565b8251156152f15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7391906156cd565b60006001615332846121da565b61533c9190615d11565b60008381526009602052604090205490915080821461539c5773ffffffffffffffffffffffffffffffffffffffff841660009081526008602090815260408083208584528252808320548484528184208190558352600990915290208190555b50600091825260096020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600881528383209183525290812055565b600a546000906153ee90600190615d11565b6000838152600b6020526040812054600a805493945090928490811061541657615416615ad0565b9060005260206000200154905080600a838154811061543757615437615ad0565b6000918252602080832090910192909255828152600b9091526040808220849055858252812055600a80548061546f5761546f615ea4565b6001900381819060005260206000200160009055905550505050565b6000615496836121da565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600860209081526040808320868452825280832085905593825260099052919091209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a000000000000000000000000000000000000000000000000000000001480610c2e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610c2e565b82805461557f90615a82565b90600052602060002090601f0160209004810192826155a157600085556155e7565b82601f106155ba57805160ff19168380011785556155e7565b828001600101855582156155e7579182015b828111156155e75782518255916020019190600101906155cc565b506155f39291506155f7565b5090565b5b808211156155f357600081556001016155f8565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611b8857600080fd5b60006020828403121561564c57600080fd5b81356125818161560c565b60005b8381101561567257818101518382015260200161565a565b8381111561271f5750506000910152565b6000815180845261569b816020860160208601615657565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006125816020830184615683565b6000602082840312156156f257600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b8857600080fd5b6000806040838503121561572e57600080fd5b8235615739816156f9565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561577f57835183529284019291840191600101615763565b50909695505050505050565b60006020828403121561579d57600080fd5b81356bffffffffffffffffffffffff8116811461258157600080fd5b6000806000606084860312156157ce57600080fd5b83356157d9816156f9565b925060208401356157e9816156f9565b929592945050506040919091013590565b6000806040838503121561580d57600080fd5b50508035926020909101359150565b6000806040838503121561582f57600080fd5b823591506020830135615841816156f9565b809150509250929050565b60006020828403121561585e57600080fd5b8135612581816156f9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff808411156158b3576158b3615869565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156158f9576158f9615869565b8160405280935085815286868601111561591257600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561593e57600080fd5b813567ffffffffffffffff81111561595557600080fd5b8201601f8101841361596657600080fd5b6136e084823560208401615898565b60006020828403121561598757600080fd5b813560ff8116811461258157600080fd5b8015158114611b8857600080fd5b600080604083850312156159b957600080fd5b82356159c4816156f9565b9150602083013561584181615998565b600080600080608085870312156159ea57600080fd5b84356159f5816156f9565b93506020850135615a05816156f9565b925060408501359150606085013567ffffffffffffffff811115615a2857600080fd5b8501601f81018713615a3957600080fd5b615a4887823560208401615898565b91505092959194509250565b60008060408385031215615a6757600080fd5b8235615a72816156f9565b91506020830135615841816156f9565b600181811c90821680615a9657607f821691505b60208210811415611bde577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615b6057615b60615aff565b5060010190565b600060208284031215615b7957600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615bb857615bb8615aff565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615bfb57615bfb615bbd565b500490565b8054600090600181811c9080831680615c1a57607f831692505b6020808410821415615c55577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b818015615c695760018114615c9857615cc5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650615cc5565b60008881526020902060005b86811015615cbd5781548b820152908501908301615ca4565b505084890196505b50505050505092915050565b6000615cdd8286615c00565b8451615ced818360208901615657565b61511f81830186615c00565b60008219821115615d0c57615d0c615aff565b500190565b600082821015615d2357615d23615aff565b500390565b60008351615d3a818460208801615657565b835190830190615d4e818360208801615657565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615d8f816017850160208801615657565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615dcc816028840160208801615657565b01602801949350505050565b600060208284031215615dea57600080fd5b815161258181615998565b600082615e0457615e04615bbd565b500690565b600081615e1857615e18615aff565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152615e7d6080830184615683565b9695505050505050565b600060208284031215615e9957600080fd5b81516125818161560c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251615ee5818460208701615657565b919091019291505056fea26469706673582212208d2e5667d706f0318413a45098f3f617b56728a8b5ceb6eb2023c85f6f56ba6264736f6c634300080b0033547572746c65547572746c652e636c75623a205468652054696d6d7920436f6c6c656374696f6e
Deployed Bytecode
0x60806040526004361061037a5760003560e01c80636352211e116101d1578063a5f0292b11610102578063d547741f116100a0578063e6226e5b1161006f578063e6226e5b14610b59578063e63ab1e914610b79578063e985e9c514610bad578063eddd0d9c14610c0357600080fd5b8063d547741f14610aee578063d642b4b114610b0e578063dfef140d14610b24578063e2fb107014610b3957600080fd5b8063c87b56dd116100dc578063c87b56dd14610a4b578063ca15c87314610a6b578063d0888d4414610a8b578063d4ba7d1214610aab57600080fd5b8063a5f0292b146109ca578063b608129c146109f7578063b88d4fde14610a2b57600080fd5b8063938f86af1161016f5780639a2fa9bb116101495780639a2fa9bb14610941578063a20e7d4714610961578063a217fddf14610995578063a22cb465146109aa57600080fd5b8063938f86af146108a757806395d89b41146108ea5780639991f016146108ff57600080fd5b80638456cb59116101ab5780638456cb59146107eb578063877c86fb146108005780639010d07c1461083457806391d148541461085457600080fd5b80636352211e1461079857806370a08231146107b8578063784b1ff0146107d857600080fd5b80632f745c59116102ab5780633f4ba83a116102495780634f6ccce7116102235780634f6ccce71461072057806351cff8d91461074057806355f804b3146107605780635c975abb1461078057600080fd5b80633f4ba83a146106cb57806342842e0e146106e0578063487458511461070057600080fd5b806336568abe1161028557806336568abe1461064257806338013f0214610662578063396478d3146106965780633ccfd60b146106b657600080fd5b80632f745c59146105ba57806332cb6b0c146105da5780633377cd661461060e57600080fd5b80631249c58b1161031857806323b872dd116102f257806323b872dd146104fe578063248a9ca31461051e5780632a55205a1461054e5780632f2ff15d1461059a57600080fd5b80631249c58b146104be578063171be8d0146104d457806318160ddd146104e957600080fd5b8063081812fc11610354578063081812fc1461042f578063095ea7b31461044f5780630e199130146104715780630e24d8e91461049e57600080fd5b806301ffc9a71461038657806305bab821146103bb57806306fdde031461040d57600080fd5b3661038157005b600080fd5b34801561039257600080fd5b506103a66103a136600461563a565b610c23565b60405190151581526020015b60405180910390f35b3480156103c757600080fd5b506014546103e89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103b2565b34801561041957600080fd5b50610422610c34565b6040516103b291906156cd565b34801561043b57600080fd5b506103e861044a3660046156e0565b610cc6565b34801561045b57600080fd5b5061046f61046a36600461571b565b610da5565b005b34801561047d57600080fd5b5061049161048c36600461571b565b610f32565b6040516103b29190615747565b3480156104aa57600080fd5b5061046f6104b936600461578b565b611000565b6104c661104b565b6040519081526020016103b2565b3480156104e057600080fd5b506104c6611183565b3480156104f557600080fd5b50600a546104c6565b34801561050a57600080fd5b5061046f6105193660046157b9565b6113ae565b34801561052a57600080fd5b506104c66105393660046156e0565b6000908152600d602052604090206001015490565b34801561055a57600080fd5b5061056e6105693660046157fa565b61144f565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152016103b2565b3480156105a657600080fd5b5061046f6105b536600461581c565b611546565b3480156105c657600080fd5b506104c66105d536600461571b565b61156b565b3480156105e657600080fd5b506104c67f00000000000000000000000000000000000000000000000000000000000003e881565b34801561061a57600080fd5b506104c67f000000000000000000000000000000000000000000000000000000000000000a81565b34801561064e57600080fd5b5061046f61065d36600461581c565b61163a565b34801561066e57600080fd5b506103e87f0000000000000000000000004b1b9f7ce4c40e9edc1453f421cf5caec384a08581565b3480156106a257600080fd5b5061046f6106b136600461584c565b6116ed565b3480156106c257600080fd5b5061046f61180c565b3480156106d757600080fd5b5061046f611b56565b3480156106ec57600080fd5b5061046f6106fb3660046157b9565b611b8b565b34801561070c57600080fd5b5061042261071b3660046156e0565b611ba6565b34801561072c57600080fd5b506104c661073b3660046156e0565b611be4565b34801561074c57600080fd5b5061046f61075b36600461584c565b611ca2565b34801561076c57600080fd5b5061046f61077b36600461592c565b61210a565b34801561078c57600080fd5b50600c5460ff166103a6565b3480156107a457600080fd5b506103e86107b33660046156e0565b612128565b3480156107c457600080fd5b506104c66107d336600461584c565b6121da565b6104916107e6366004615975565b6122a8565b3480156107f757600080fd5b5061046f612537565b34801561080c57600080fd5b506103e87f0000000000000000000000006a31aca4d2f7398f04d9b6ffae2d898d9a8e793881565b34801561084057600080fd5b506103e861084f3660046157fa565b612569565b34801561086057600080fd5b506103a661086f36600461581c565b6000918252600d6020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156108b357600080fd5b506103e86108c236600461584c565b60156020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156108f657600080fd5b50610422612588565b34801561090b57600080fd5b50601054610924906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff90911681526020016103b2565b34801561094d57600080fd5b506104c661095c36600461584c565b612597565b34801561096d57600080fd5b506104c67fd8a7a79547af723ee3e12b59a480111268d8969c634e1a34a144d2c8b91d635b81565b3480156109a157600080fd5b506104c6600081565b3480156109b657600080fd5b5061046f6109c53660046159a6565b612672565b3480156109d657600080fd5b506013546103e89073ffffffffffffffffffffffffffffffffffffffff1681565b348015610a0357600080fd5b506103e87f000000000000000000000000a8de5367290ed79658a9f9b9ae1f633c355f1e1f81565b348015610a3757600080fd5b5061046f610a463660046159d4565b61267d565b348015610a5757600080fd5b50610422610a663660046156e0565b612725565b348015610a7757600080fd5b506104c6610a863660046156e0565b61280e565b348015610a9757600080fd5b506104c6610aa636600461584c565b612825565b348015610ab757600080fd5b506103e8610ac63660046156e0565b60166020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610afa57600080fd5b5061046f610b0936600461581c565b61286f565b348015610b1a57600080fd5b506104c6600f5481565b348015610b3057600080fd5b506104c6612894565b348015610b4557600080fd5b506104c6610b543660046156e0565b6129d0565b348015610b6557600080fd5b50610491610b743660046156e0565b612a7d565b348015610b8557600080fd5b506104c67f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b348015610bb957600080fd5b506103a6610bc8366004615a54565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610c0f57600080fd5b5061046f610c1e3660046156e0565b612de7565b6000610c2e82612feb565b92915050565b606060028054610c4390615a82565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6f90615a82565b8015610cbc5780601f10610c9157610100808354040283529160200191610cbc565b820191906000526020600020905b815481529060010190602001808311610c9f57829003601f168201915b5050505050905090565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16610d7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000610db082612128565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610e6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610d73565b3373ffffffffffffffffffffffffffffffffffffffff82161480610e975750610e978133610bc8565b610f23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610d73565b610f2d8383613041565b505050565b60606000610f3f816130e1565b6000610f4d600c5460ff1690565b90508015610f5d57610f5d6130eb565b60008467ffffffffffffffff811115610f7857610f78615869565b604051908082528060200260200182016040528015610fa1578160200160208202803683370190505b50905060005b85811015610fe757610fb8876131cc565b828281518110610fca57610fca615ad0565b602090810291909101015280610fdf81615b2e565b915050610fa7565b5092508015610ff857610ff86132d5565b505092915050565b600061100b816130e1565b50601080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b6000611059600c5460ff1690565b156110c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b6000806110cb613395565b915091508134101580156110df5750803411155b61116b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c657220646964206e6f7420737570706c7920636f7260448201527f7265637420616d6f756e74206f662046544d00000000000000000000000000006064820152608401610d73565b6111736133df565b61117c336131cc565b9250505090565b6000611191600c5460ff1690565b156111f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b600f5473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006a31aca4d2f7398f04d9b6ffae2d898d9a8e79381663dd62ed3e336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb9190615b67565b1015611359576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c6572206d7573742070726f7669646520617070726f60448201527f76616c20746f207370656e6420746f6b656e00000000000000000000000000006064820152608401610d73565b6113a033600f5473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006a31aca4d2f7398f04d9b6ffae2d898d9a8e7938169190309061349c565b6113a9336131cc565b905090565b6113b83382613578565b611444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610d73565b610f2d8383836136e8565b600082815260016020908152604080832081518083019092525473ffffffffffffffffffffffffffffffffffffffff8116808352740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff1692820192909252829161150a57506040805180820190915260005473ffffffffffffffffffffffffffffffffffffffff811682527401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1660208201525b60208101516000906127109061152e906bffffffffffffffffffffffff1687615b80565b6115389190615bec565b915196919550909350505050565b6000828152600d6020526040902060010154611561816130e1565b610f2d8383613960565b6000611576836121da565b8210611604576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610d73565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b73ffffffffffffffffffffffffffffffffffffffff811633146116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610d73565b6116e98282613982565b5050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260409020541661177b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420616e206f726967696e616c206d696e746572000000000000000000006044820152606401610d73565b73ffffffffffffffffffffffffffffffffffffffff8082166000908152601560205260408082205481517f5be7fde80000000000000000000000000000000000000000000000000000000081529151931692635be7fde89260048084019391929182900301818387803b1580156117f157600080fd5b505af1158015611805573d6000803e3d6000fd5b5050505050565b6000611817816130e1565b4761187e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f636f6e747261637420686173206e6f2062616c616e63650000000000000000006044820152606401610d73565b6013546000906118a39073ffffffffffffffffffffffffffffffffffffffff16612df8565b90508073ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156118ed57600080fd5b505af1158015611901573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166318f9b0236119283390565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152605a6024820152604401600060405180830381600087803b15801561199557600080fd5b505af11580156119a9573d6000803e3d6000fd5b505050507f000000000000000000000000aacb16dffe087c82d6151d978c8f7ef57330656173ffffffffffffffffffffffffffffffffffffffff166119eb3390565b73ffffffffffffffffffffffffffffffffffffffff1614611aaf576040517f18f9b02300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000aacb16dffe087c82d6151d978c8f7ef57330656181166004830152600a60248301528216906318f9b02390604401600060405180830381600087803b158015611a9657600080fd5b505af1158015611aaa573d6000803e3d6000fd5b505050505b60405173ffffffffffffffffffffffffffffffffffffffff8216904780156108fc02916000818181858888f19350505050158015611af1573d6000803e3d6000fd5b508073ffffffffffffffffffffffffffffffffffffffff16635be7fde86040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b3a57600080fd5b505af1158015611b4e573d6000803e3d6000fd5b505050505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a611b80816130e1565b611b886130eb565b50565b610f2d8383836040518060200160405280600081525061267d565b60607fd8a7a79547af723ee3e12b59a480111268d8969c634e1a34a144d2c8b91d635b611bd2816130e1565b611bdb836139a4565b91505b50919050565b6000611bef600a5490565b8210611c7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610d73565b600a8281548110611c9057611c90615ad0565b90600052602060002001549050919050565b6000611cad816130e1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611d17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3b9190615b67565b611da1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f636f6e747261637420686173206e6f2062616c616e6365206f6620746f6b656e6044820152606401610d73565b601354600090611dc69073ffffffffffffffffffffffffffffffffffffffff16612df8565b90508073ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e1057600080fd5b505af1158015611e24573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166318f9b023611e4b3390565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152605a6024820152604401600060405180830381600087803b158015611eb857600080fd5b505af1158015611ecc573d6000803e3d6000fd5b505050507f000000000000000000000000aacb16dffe087c82d6151d978c8f7ef57330656173ffffffffffffffffffffffffffffffffffffffff16611f0e3390565b73ffffffffffffffffffffffffffffffffffffffff1614611fd2576040517f18f9b02300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000aacb16dffe087c82d6151d978c8f7ef57330656181166004830152600a60248301528216906318f9b02390604401600060405180830381600087803b158015611fb957600080fd5b505af1158015611fcd573d6000803e3d6000fd5b505050505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015261208490829073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015612042573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120669190615b67565b73ffffffffffffffffffffffffffffffffffffffff86169190613a2a565b6040517f580fc80a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015282169063580fc80a90602401600060405180830381600087803b1580156120ed57600080fd5b505af1158015612101573d6000803e3d6000fd5b50505050505050565b6000612115816130e1565b8151610f2d906011906020850190615573565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610c2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610d73565b600073ffffffffffffffffffffffffffffffffffffffff821661227f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610d73565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205490565b60606122b6600c5460ff1690565b1561231d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b7f000000000000000000000000000000000000000000000000000000000000000a8260ff1611156123d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4552433732313a206d757374206d696e74206c657373207468616e207468652060448201527f6d6178696d756d20636f756e7420706572206d696e74000000000000000000006064820152608401610d73565b6000806123db613395565b90925090506123ed60ff851683615b80565b3410158015612408575061240460ff851682615b80565b3411155b612494576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c657220646964206e6f7420737570706c7920636f7260448201527f7265637420616d6f756e74206f662046544d00000000000000000000000000006064820152608401610d73565b60008460ff1667ffffffffffffffff8111156124b2576124b2615869565b6040519080825280602002602001820160405280156124db578160200160208202803683370190505b50905060005b8560ff16811015612524576124f5336131cc565b82828151811061250757612507615ad0565b60209081029190910101528061251c81615b2e565b9150506124e1565b5061252d6133df565b925050505b919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a612561816130e1565b611b886132d5565b6000828152600e602052604081206125819083613a80565b9392505050565b606060038054610c4390615a82565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260408120549091166125cd57506000919050565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260156020526040908190205490517f5eebea20000000000000000000000000000000000000000000000000000000008152600481019290925290911690635eebea20906024015b602060405180830381865afa15801561264e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2e9190615b67565b6116e9338383613a8c565b6126873383613578565b612713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610d73565b61271f84848484613bba565b50505050565b60008181526004602052604090205460609073ffffffffffffffffffffffffffffffffffffffff166127d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006064820152608401610d73565b60116127e4836139a4565b60126040516020016127f893929190615cd1565b6040516020818303038152906040529050919050565b6000818152600e60205260408120610c2e90613c5d565b600080612831816130e1565b600061283f600c5460ff1690565b9050801561284f5761284f6130eb565b612858846131cc565b92508015612868576128686132d5565b5050919050565b6000828152600d602052604090206001015461288a816130e1565b610f2d8383613982565b600f546040517ffd5cb07d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a8de5367290ed79658a9f9b9ae1f633c355f1e1f811660048301527f0000000000000000000000006a31aca4d2f7398f04d9b6ffae2d898d9a8e793881166024830152604482019290925260009182917f0000000000000000000000004b1b9f7ce4c40e9edc1453f421cf5caec384a0859091169063fd5cb07d90606401602060405180830381865afa15801561297a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299e9190615b67565b601054909150612710906129c0906bffffffffffffffffffffffff1683615b80565b6129ca9190615bec565b91505090565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16612a0157506000919050565b60008281526016602081815260408084205473ffffffffffffffffffffffffffffffffffffffff90811680865260158452828620549588905293909252517f5eebea2000000000000000000000000000000000000000000000000000000000815260048101929092529190911690635eebea2090602401612631565b6060612a8b600c5460ff1690565b15612af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b7f000000000000000000000000000000000000000000000000000000000000000a821115612ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4552433732313a206d757374206d696e74206c657373207468616e207468652060448201527f6d6178696d756d20636f756e7420706572206d696e74000000000000000000006064820152608401610d73565b600082600f54612bb29190615b80565b90508073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006a31aca4d2f7398f04d9b6ffae2d898d9a8e79381663dd62ed3e336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015612c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c859190615b67565b1015612d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c6572206d7573742070726f7669646520617070726f60448201527f76616c20746f207370656e6420746f6b656e00000000000000000000000000006064820152608401610d73565b612d557f0000000000000000000000006a31aca4d2f7398f04d9b6ffae2d898d9a8e793873ffffffffffffffffffffffffffffffffffffffff1633308461349c565b60008367ffffffffffffffff811115612d7057612d70615869565b604051908082528060200260200182016040528015612d99578160200160208202803683370190505b50905060005b84811015612ddf57612db0336131cc565b828281518110612dc257612dc2615ad0565b602090810291909101015280612dd781615b2e565b915050612d9f565b509392505050565b6000612df2816130e1565b50600f55565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f091505073ffffffffffffffffffffffffffffffffffffffff8116612532576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f455243313136373a20637265617465206661696c6564000000000000000000006044820152606401610d73565b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166116e9576000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612f6b3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006125818373ffffffffffffffffffffffffffffffffffffffff8416613c67565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f5a05180f000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82613cb6565b600081815260066020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061309b82612128565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611b888133613d0c565b600c5460ff16613157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610d73565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000806131d8600a5490565b90507f00000000000000000000000000000000000000000000000000000000000003e8613206826001615cf9565b111561326e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6d696e7420636f6d706c657465640000000000000000000000000000000000006044820152606401610d73565b600061327b826001615cf9565b90506132878185613dde565b61329184826140c6565b60008181526016602090815260408083205473ffffffffffffffffffffffffffffffffffffffff9081168452601590925290912054612581918391166101f46140e0565b600c5460ff1615613342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586131a23390565b60008060006133a2612894565b90506127106133b382612616615b80565b6133bd9190615bec565b92506127106133ce8261280a615b80565b6133d89190615bec565b9150509091565b6040517f1c1b877200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a8de5367290ed79658a9f9b9ae1f633c355f1e1f811660048301527f0000000000000000000000004b1b9f7ce4c40e9edc1453f421cf5caec384a0851690631c1b877290602401600060405180830381600087803b15801561348857600080fd5b505af115801561271f573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261271f9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261426a565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16613629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610d73565b600061363483612128565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806136a357508373ffffffffffffffffffffffffffffffffffffffff1661368b84610cc6565b73ffffffffffffffffffffffffffffffffffffffff16145b806136e0575073ffffffffffffffffffffffffffffffffffffffff80821660009081526007602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661370882612128565b73ffffffffffffffffffffffffffffffffffffffff16146137ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff821661384d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610d73565b613858838383614376565b613863600082613041565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600560205260408120805460019290613899908490615d11565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604081208054600192906138d4908490615cf9565b909155505060008181526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4610f2d838383614381565b61396a8282612ed5565b6000828152600e60205260409020610f2d9082612fc9565b61398c82826144ae565b6000828152600e60205260409020610f2d9082614569565b6060610c2e60206139d47f884f3377a0ee1b663705bad00477595feb99de1caa6c1672dfdc194d39d26b7361458b565b6139dd8561458b565b6040516020016139ee929190615d28565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120906146bd565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f2d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016134f6565b60006125818383614900565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613b22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d73565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526007602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b613bc58484846136e8565b613bd18484848461492a565b61271f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b6000610c2e825490565b6000818152600183016020526040812054613cae57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c2e565b506000610c2e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82614b1a565b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166116e957613d648173ffffffffffffffffffffffffffffffffffffffff1660146146bd565b613d6f8360206146bd565b604051602001613d80929190615d57565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610d73916004016156cd565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260409020541661407357601354613e2c9073ffffffffffffffffffffffffffffffffffffffff16612df8565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526015602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169490931693841790925581517f8129fc1c0000000000000000000000000000000000000000000000000000000081529151638129fc1c92600480820193929182900301818387803b158015613ecb57600080fd5b505af1158015613edf573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff818116600090815260156020526040908190205460145491517f18f9b023000000000000000000000000000000000000000000000000000000008152918316600483015260016024830152909116906318f9b02390604401600060405180830381600087803b158015613f6a57600080fd5b505af1158015613f7e573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff818116600081815260156020526040908190205490517f18f9b023000000000000000000000000000000000000000000000000000000008152600481019290925260016024830152909116906318f9b02390604401600060405180830381600087803b15801561400657600080fd5b505af115801561401a573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff808316600081815260156020526040808220549051929450869316917fafa098bd63d0c6b0ddc6f328aba242372f2fe7974da70f45af0745ce98162f5c9190a45b60009182526016602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6116e9828260405180602001604052806000815250614b25565b6127106bffffffffffffffffffffffff82161115614180576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff82166141fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610d73565b60408051808201825273ffffffffffffffffffffffffffffffffffffffff93841681526bffffffffffffffffffffffff9283166020808301918252600096875260019052919094209351905190911674010000000000000000000000000000000000000000029116179055565b60006142cc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614bc89092919063ffffffff16565b805190915015610f2d57808060200190518101906142ea9190615dd8565b610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d73565b610f2d838383614bd7565b60008181526016602052604090205473ffffffffffffffffffffffffffffffffffffffff16156144445760008181526016602090815260408083205473ffffffffffffffffffffffffffffffffffffffff908116845260159092528083205481517f5be7fde80000000000000000000000000000000000000000000000000000000081529151921692635be7fde89260048084019382900301818387803b15801561442b57600080fd5b505af115801561443f573d6000803e3d6000fd5b505050505b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635be7fde86040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156120ed57600080fd5b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156116e9576000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006125818373ffffffffffffffffffffffffffffffffffffffff8416614c75565b6060816145cb57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156145f557806145df81615b2e565b91506145ee9050600a83615bec565b91506145cf565b60008167ffffffffffffffff81111561461057614610615869565b6040519080825280601f01601f19166020018201604052801561463a576020820181803683370190505b5090505b841561252d5761464f600183615d11565b915061465c600a86615df5565b614667906030615cf9565b60f81b81838151811061467c5761467c615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506146b6600a86615bec565b945061463e565b606060006146cc836002615b80565b6146d7906002615cf9565b67ffffffffffffffff8111156146ef576146ef615869565b6040519080825280601f01601f191660200182016040528015614719576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061475057614750615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106147b3576147b3615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006147ef846002615b80565b6147fa906001615cf9565b90505b6001811115614897577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061483b5761483b615ad0565b1a60f81b82828151811061485157614851615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361489081615e09565b90506147fd565b508315612581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d73565b600082600001828154811061491757614917615ad0565b9060005260206000200154905092915050565b600073ffffffffffffffffffffffffffffffffffffffff84163b15614b0f576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a02906149a1903390899088908890600401615e3e565b6020604051808303816000875af19250505080156149fa575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526149f791810190615e87565b60015b614ac4573d808015614a28576040519150601f19603f3d011682016040523d82523d6000602084013e614a2d565b606091505b508051614abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506136e0565b506001949350505050565b6000610c2e82614d68565b614b2f8383614dbe565b614b3c600084848461492a565b610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b60606136e08484600085614f94565b614be283838361512a565b600c5460ff1615610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201527f68696c65207061757365640000000000000000000000000000000000000000006064820152608401610d73565b60008181526001830160205260408120548015614d5e576000614c99600183615d11565b8554909150600090614cad90600190615d11565b9050818114614d12576000866000018281548110614ccd57614ccd615ad0565b9060005260206000200154905080876000018481548110614cf057614cf0615ad0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614d2357614d23615ea4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610c2e565b6000915050610c2e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82615230565b73ffffffffffffffffffffffffffffffffffffffff8216614e3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d73565b60008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1615614ec7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d73565b614ed360008383614376565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600560205260408120805460019290614f09908490615cf9565b909155505060008181526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46116e960008383614381565b606082471015615026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff85163b6150a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d73565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516150cd9190615ed3565b60006040518083038185875af1925050503d806000811461510a576040519150601f19603f3d011682016040523d82523d6000602084013e61510f565b606091505b509150915061511f8282866152d2565b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166151925761518d81600a80546000838152600b60205260408120829055600182018355919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80155565b6151cf565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146151cf576151cf8382615325565b73ffffffffffffffffffffffffffffffffffffffff82166151f357610f2d816153dc565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610f2d57610f2d828261548b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806152c357507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610c2e5750610c2e826154dc565b606083156152e1575081612581565b8251156152f15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7391906156cd565b60006001615332846121da565b61533c9190615d11565b60008381526009602052604090205490915080821461539c5773ffffffffffffffffffffffffffffffffffffffff841660009081526008602090815260408083208584528252808320548484528184208190558352600990915290208190555b50600091825260096020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600881528383209183525290812055565b600a546000906153ee90600190615d11565b6000838152600b6020526040812054600a805493945090928490811061541657615416615ad0565b9060005260206000200154905080600a838154811061543757615437615ad0565b6000918252602080832090910192909255828152600b9091526040808220849055858252812055600a80548061546f5761546f615ea4565b6001900381819060005260206000200160009055905550505050565b6000615496836121da565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600860209081526040808320868452825280832085905593825260099052919091209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a000000000000000000000000000000000000000000000000000000001480610c2e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610c2e565b82805461557f90615a82565b90600052602060002090601f0160209004810192826155a157600085556155e7565b82601f106155ba57805160ff19168380011785556155e7565b828001600101855582156155e7579182015b828111156155e75782518255916020019190600101906155cc565b506155f39291506155f7565b5090565b5b808211156155f357600081556001016155f8565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611b8857600080fd5b60006020828403121561564c57600080fd5b81356125818161560c565b60005b8381101561567257818101518382015260200161565a565b8381111561271f5750506000910152565b6000815180845261569b816020860160208601615657565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006125816020830184615683565b6000602082840312156156f257600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b8857600080fd5b6000806040838503121561572e57600080fd5b8235615739816156f9565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561577f57835183529284019291840191600101615763565b50909695505050505050565b60006020828403121561579d57600080fd5b81356bffffffffffffffffffffffff8116811461258157600080fd5b6000806000606084860312156157ce57600080fd5b83356157d9816156f9565b925060208401356157e9816156f9565b929592945050506040919091013590565b6000806040838503121561580d57600080fd5b50508035926020909101359150565b6000806040838503121561582f57600080fd5b823591506020830135615841816156f9565b809150509250929050565b60006020828403121561585e57600080fd5b8135612581816156f9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff808411156158b3576158b3615869565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156158f9576158f9615869565b8160405280935085815286868601111561591257600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561593e57600080fd5b813567ffffffffffffffff81111561595557600080fd5b8201601f8101841361596657600080fd5b6136e084823560208401615898565b60006020828403121561598757600080fd5b813560ff8116811461258157600080fd5b8015158114611b8857600080fd5b600080604083850312156159b957600080fd5b82356159c4816156f9565b9150602083013561584181615998565b600080600080608085870312156159ea57600080fd5b84356159f5816156f9565b93506020850135615a05816156f9565b925060408501359150606085013567ffffffffffffffff811115615a2857600080fd5b8501601f81018713615a3957600080fd5b615a4887823560208401615898565b91505092959194509250565b60008060408385031215615a6757600080fd5b8235615a72816156f9565b91506020830135615841816156f9565b600181811c90821680615a9657607f821691505b60208210811415611bde577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615b6057615b60615aff565b5060010190565b600060208284031215615b7957600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615bb857615bb8615aff565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615bfb57615bfb615bbd565b500490565b8054600090600181811c9080831680615c1a57607f831692505b6020808410821415615c55577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b818015615c695760018114615c9857615cc5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650615cc5565b60008881526020902060005b86811015615cbd5781548b820152908501908301615ca4565b505084890196505b50505050505092915050565b6000615cdd8286615c00565b8451615ced818360208901615657565b61511f81830186615c00565b60008219821115615d0c57615d0c615aff565b500190565b600082821015615d2357615d23615aff565b500390565b60008351615d3a818460208801615657565b835190830190615d4e818360208801615657565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615d8f816017850160208801615657565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615dcc816028840160208801615657565b01602801949350505050565b600060208284031215615dea57600080fd5b815161258181615998565b600082615e0457615e04615bbd565b500690565b600081615e1857615e18615aff565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152615e7d6080830184615683565b9695505050505050565b600060208284031215615e9957600080fd5b81516125818161560c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251615ee5818460208701615657565b919091019291505056fea26469706673582212208d2e5667d706f0318413a45098f3f617b56728a8b5ceb6eb2023c85f6f56ba6264736f6c634300080b0033
Deployed Bytecode Sourcemap
109057:14998:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123720:332;;;;;;;;;;-1:-1:-1;123720:332:0;;;;;:::i;:::-;;:::i;:::-;;;611:14:1;;604:22;586:41;;574:2;559:18;123720:332:0;;;;;;;;110261:43;;;;;;;;;;-1:-1:-1;110261:43:0;;;;;;;;;;;839:42:1;827:55;;;809:74;;797:2;782:18;110261:43:0;638:251:1;30644:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;32338:308::-;;;;;;;;;;-1:-1:-1;32338:308:0;;;;;:::i;:::-;;:::i;31861:411::-;;;;;;;;;;-1:-1:-1;31861:411:0;;;;;:::i;:::-;;:::i;:::-;;118395:370;;;;;;;;;;-1:-1:-1;118395:370:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;119787:148::-;;;;;;;;;;-1:-1:-1;119787:148:0;;;;;:::i;:::-;;:::i;114772:351::-;;;:::i;:::-;;;3679:25:1;;;3667:2;3652:18;114772:351:0;3533:177:1;116170:430:0;;;;;;;;;;;;;:::i;53254:113::-;;;;;;;;;;-1:-1:-1;53342:10:0;:17;53254:113;;33257:376;;;;;;;;;;-1:-1:-1;33257:376:0;;;;;:::i;:::-;;:::i;71270:181::-;;;;;;;;;;-1:-1:-1;71270:181:0;;;;;:::i;:::-;71389:7;71421:12;;;:6;:12;;;;;:22;;;;71270:181;46204:507;;;;;;;;;;-1:-1:-1;46204:507:0;;;;;:::i;:::-;;:::i;:::-;;;;5000:42:1;4988:55;;;4970:74;;5075:2;5060:18;;5053:34;;;;4943:18;46204:507:0;4796:297:1;71713:188:0;;;;;;;;;;-1:-1:-1;71713:188:0;;;;;:::i;:::-;;:::i;52835:343::-;;;;;;;;;;-1:-1:-1;52835:343:0;;;;;:::i;:::-;;:::i;109986:42::-;;;;;;;;;;;;;;;109524:49;;;;;;;;;;;;;;;72843:287;;;;;;;;;;-1:-1:-1;72843:287:0;;;;;:::i;:::-;;:::i;109833:120::-;;;;;;;;;;;;;;;113685:245;;;;;;;;;;-1:-1:-1;113685:245:0;;;;;:::i;:::-;;:::i;121662:501::-;;;;;;;;;;;;;:::i;119505:77::-;;;;;;;;;;;;;:::i;33704:185::-;;;;;;;;;;-1:-1:-1;33704:185:0;;;;;:::i;:::-;;:::i;120766:193::-;;;;;;;;;;-1:-1:-1;120766:193:0;;;;;:::i;:::-;;:::i;53444:320::-;;;;;;;;;;-1:-1:-1;53444:320:0;;;;;:::i;:::-;;:::i;122280:593::-;;;;;;;;;;-1:-1:-1;122280:593:0;;;;;:::i;:::-;;:::i;120074:143::-;;;;;;;;;;-1:-1:-1;120074:143:0;;;;;:::i;:::-;;:::i;59964:86::-;;;;;;;;;;-1:-1:-1;60035:7:0;;;;59964:86;;30251:326;;;;;;;;;;-1:-1:-1;30251:326:0;;;;;:::i;:::-;;:::i;29894:295::-;;;;;;;;;;-1:-1:-1;29894:295:0;;;;;:::i;:::-;;:::i;115283:738::-;;;;;;:::i;:::-;;:::i;119424:73::-;;;;;;;;;;;;;:::i;109727:99::-;;;;;;;;;;;;;;;89471:203;;;;;;;;;;-1:-1:-1;89471:203:0;;;;;:::i;:::-;;:::i;69680:197::-;;;;;;;;;;-1:-1:-1;69680:197:0;;;;;:::i;:::-;69811:4;69840:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;;;;69680:197;110311:65;;;;;;;;;;-1:-1:-1;110311:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;30813:104;;;;;;;;;;;;;:::i;109580:33::-;;;;;;;;;;-1:-1:-1;109580:33:0;;;;;;;;;;;8481:26:1;8469:39;;;8451:58;;8439:2;8424:18;109580:33:0;8307:208:1;113330:248:0;;;;;;;;;;-1:-1:-1;113330:248:0;;;;;:::i;:::-;;:::i;110580:64::-;;;;;;;;;;;;110619:25;110580:64;;68709:49;;;;;;;;;;-1:-1:-1;68709:49:0;68754:4;68709:49;;32718:187;;;;;;;;;;-1:-1:-1;32718:187:0;;;;;:::i;:::-;;:::i;110160:94::-;;;;;;;;;;-1:-1:-1;110160:94:0;;;;;;;;109620:100;;;;;;;;;;;;;;;33960:365;;;;;;;;;;-1:-1:-1;33960:365:0;;;;;:::i;:::-;;:::i;121030:494::-;;;;;;;;;;-1:-1:-1;121030:494:0;;;;;:::i;:::-;;:::i;89848:192::-;;;;;;;;;;-1:-1:-1;89848:192:0;;;;;:::i;:::-;;:::i;117874:200::-;;;;;;;;;;-1:-1:-1;117874:200:0;;;;;:::i;:::-;;:::i;110383:55::-;;;;;;;;;;-1:-1:-1;110383:55:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;72146:190;;;;;;;;;;-1:-1:-1;72146:190:0;;;;;:::i;:::-;;:::i;109480:37::-;;;;;;;;;;;;;;;;113974:263;;;;;;;;;;;;;:::i;112919:305::-;;;;;;;;;;-1:-1:-1;112919:305:0;;;;;:::i;:::-;;:::i;116760:875::-;;;;;;;;;;-1:-1:-1;116760:875:0;;;;;:::i;:::-;;:::i;110511:62::-;;;;;;;;;;;;110549:24;110511:62;;32976:214;;;;;;;;;;-1:-1:-1;32976:214:0;;;;;:::i;:::-;33147:25;;;;33118:4;33147:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;32976:214;119633:146;;;;;;;;;;-1:-1:-1;119633:146:0;;;;;:::i;:::-;;:::i;123720:332::-;123979:4;124008:36;124032:11;124008:23;:36::i;:::-;124001:43;123720:332;-1:-1:-1;;123720:332:0:o;30644:100::-;30698:13;30731:5;30724:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30644:100;:::o;32338:308::-;32459:7;35961:16;;;:7;:16;;;;;;:30;:16;32484:110;;;;;;;10867:2:1;32484:110:0;;;10849:21:1;10906:2;10886:18;;;10879:30;10945:34;10925:18;;;10918:62;11016:14;10996:18;;;10989:42;11048:19;;32484:110:0;;;;;;;;;-1:-1:-1;32614:24:0;;;;:15;:24;;;;;;;;;32338:308::o;31861:411::-;31942:13;31958:23;31973:7;31958:14;:23::i;:::-;31942:39;;32006:5;32000:11;;:2;:11;;;;31992:57;;;;;;;11280:2:1;31992:57:0;;;11262:21:1;11319:2;11299:18;;;11292:30;11358:34;11338:18;;;11331:62;11429:3;11409:18;;;11402:31;11450:19;;31992:57:0;11078:397:1;31992:57:0;24818:10;32084:21;;;;;:62;;-1:-1:-1;32109:37:0;32126:5;24818:10;32976:214;:::i;32109:37::-;32062:168;;;;;;;11682:2:1;32062:168:0;;;11664:21:1;11721:2;11701:18;;;11694:30;11760:34;11740:18;;;11733:62;11831:26;11811:18;;;11804:54;11875:19;;32062:168:0;11480:420:1;32062:168:0;32243:21;32252:2;32256:7;32243:8;:21::i;:::-;31931:341;31861:411;;:::o;118395:370::-;118542:16;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;60756:14:::1;60773:8;60035:7:::0;;;;;59964:86;60773:8:::1;60756:25;;60796:9;60792:52;;;60822:10;:8;:10::i;:::-;118576:25:::2;118618:5;118604:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;118604:20:0::2;;118576:48;;118642:9;118637:93;118661:5;118657:1;:9;118637:93;;;118702:16;118714:3;118702:11;:16::i;:::-;118688:8;118697:1;118688:11;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:30;118668:3;::::2;::::0;::::2;:::i;:::-;;;;118637:93;;;-1:-1:-1::0;118749:8:0;-1:-1:-1;60870:9:0::1;60866:50;;;60896:8;:6;:8::i;:::-;60745:178;118395:370:::0;;;;;:::o;119787:148::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;-1:-1:-1;119901:11:0::1;:26:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;119787:148::o;114772:351::-;114826:7;60290:8;60035:7;;;;;59964:86;60290:8;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;114847:11:::1;114860::::0;114875:21:::1;:19;:21::i;:::-;114846:50;;;;114942:3;114929:9;:16;;:36;;;;;114962:3;114949:9;:16;;114929:36;114907:136;;;::::0;::::1;::::0;;13030:2:1;114907:136:0::1;::::0;::::1;13012:21:1::0;13069:2;13049:18;;;13042:30;13108:34;13088:18;;;13081:62;13179:20;13159:18;;;13152:48;13217:19;;114907:136:0::1;12828:414:1::0;114907:136:0::1;115056:14;:12;:14::i;:::-;115090:25;24818:10:::0;115090:11:::1;:25::i;:::-;115083:32;;;;114772:351:::0;:::o;116170:430::-;116225:7;60290:8;60035:7;;;;;59964:86;60290:8;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;116323:11:::1;::::0;116267:23:::1;:13;:23;;24818:10:::0;116267:52:::1;::::0;;::::1;::::0;;;;;;13431:42:1;13500:15;;;116267:52:0::1;::::0;::::1;13482:34:1::0;116313:4:0::1;13532:18:1::0;;;13525:43;13394:18;;116267:52:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:67;;116245:167;;;::::0;::::1;::::0;;13970:2:1;116245:167:0::1;::::0;::::1;13952:21:1::0;14009:2;13989:18;;;13982:30;14048:34;14028:18;;;14021:62;14119:20;14099:18;;;14092:48;14157:19;;116245:167:0::1;13768:414:1::0;116245:167:0::1;116425:122;24818:10:::0;116525:11:::1;::::0;116425:30:::1;:13;:30;::::0;:122;116505:4:::1;::::0;116425:30:::1;:122::i;:::-;116567:25;24818:10:::0;115090:11:::1;:25::i;116567:::-;116560:32;;116170:430:::0;:::o;33257:376::-;33466:41;24818:10;33499:7;33466:18;:41::i;:::-;33444:140;;;;;;;14389:2:1;33444:140:0;;;14371:21:1;14428:2;14408:18;;;14401:30;14467:34;14447:18;;;14440:62;14538:19;14518:18;;;14511:47;14575:19;;33444:140:0;14187:413:1;33444:140:0;33597:28;33607:4;33613:2;33617:7;33597:9;:28::i;46204:507::-;46348:7;46411:27;;;:17;:27;;;;;;;;46382:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;46348:7;;46451:92;;-1:-1:-1;46502:29:0;;;;;;;;;-1:-1:-1;46502:29:0;;;;;;;;;;;;;;;46451:92;46593:23;;;;46555:21;;47077:5;;46580:36;;46579:71;46580:36;:10;:36;:::i;:::-;46579:71;;;;:::i;:::-;46671:16;;;;;-1:-1:-1;46204:507:0;;-1:-1:-1;;;;46204:507:0:o;71713:188::-;71389:7;71421:12;;;:6;:12;;;;;:22;;;69200:16;69211:4;69200:10;:16::i;:::-;71868:25:::1;71879:4;71885:7;71868:10;:25::i;52835:343::-:0;52977:7;53032:23;53049:5;53032:16;:23::i;:::-;53024:5;:31;53002:124;;;;;;;15354:2:1;53002:124:0;;;15336:21:1;15393:2;15373:18;;;15366:30;15432:34;15412:18;;;15405:62;15503:13;15483:18;;;15476:41;15534:19;;53002:124:0;15152:407:1;53002:124:0;-1:-1:-1;53144:19:0;;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;52835:343::o;72843:287::-;72985:23;;;24818:10;72985:23;72963:120;;;;;;;15766:2:1;72963:120:0;;;15748:21:1;15805:2;15785:18;;;15778:30;15844:34;15824:18;;;15817:62;15915:17;15895:18;;;15888:45;15950:19;;72963:120:0;15564:411:1;72963:120:0;73096:26;73108:4;73114:7;73096:11;:26::i;:::-;72843:287;;:::o;113685:245::-;113767:52;113775:29;;;113817:1;113775:29;;;:21;:29;;;;;;;113745:124;;;;;;;16182:2:1;113745:124:0;;;16164:21:1;16221:2;16201:18;;;16194:30;16260:24;16240:18;;;16233:52;16302:18;;113745:124:0;15980:346:1;113745:124:0;113880:29;;;;;;;;:21;:29;;;;;;;:42;;;;;;;:29;;;:40;;:42;;;;;:29;;:42;;;;;;:29;;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113685:245;:::o;121662:501::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;121737:21:::1;121729:62;;;::::0;::::1;::::0;;16533:2:1;121729:62:0::1;::::0;::::1;16515:21:1::0;16572:2;16552:18;;;16545:30;16611:25;16591:18;;;16584:53;16654:18;;121729:62:0::1;16331:347:1::0;121729:62:0::1;121849:16;::::0;121804:25:::1;::::0;121849:24:::1;::::0;:16:::1;;:22;:24::i;:::-;121804:70;;121885:8;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;121917:8;:17;;;121935:12;24818:10:::0;;24738:98;121935:12:::1;121917:35;::::0;;::::1;::::0;;;;;;5000:42:1;4988:55;;;121917:35:0::1;::::0;::::1;4970:74:1::0;121949:2:0::1;5060:18:1::0;;;5053:34;4943:18;;121917:35:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;121985:8;121969:24;;:12;24818:10:::0;;24738:98;121969:12:::1;:24;;;121965:88;;122010:31;::::0;;;;:17:::1;122028:8;4988:55:1::0;;122010:31:0::1;::::0;::::1;4970:74:1::0;122038:2:0::1;5060:18:1::0;;;5053:34;122010:17:0;::::1;::::0;::::1;::::0;4943:18:1;;122010:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;121965:88;122065:58;::::0;:35:::1;::::0;::::1;::::0;122101:21:::1;122065:58:::0;::::1;;;::::0;::::1;::::0;;;122101:21;122065:35;:58;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;122134:8;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;121718:445;121662:501:::0;:::o;119505:77::-;110549:24;69200:16;69211:4;69200:10;:16::i;:::-;119564:10:::1;:8;:10::i;:::-;119505:77:::0;:::o;33704:185::-;33842:39;33859:4;33865:2;33869:7;33842:39;;;;;;;;;;;;:16;:39::i;120766:193::-;120887:13;110619:25;69200:16;69211:4;69200:10;:16::i;:::-;120925:26:::1;120943:7;120925:17;:26::i;:::-;120918:33;;69227:1;120766:193:::0;;;;:::o;53444:320::-;53564:7;53619:30;53342:10;:17;;53254:113;53619:30;53611:5;:38;53589:132;;;;;;;17507:2:1;53589:132:0;;;17489:21:1;17546:2;17526:18;;;17519:30;17585:34;17565:18;;;17558:62;17656:14;17636:18;;;17629:42;17688:19;;53589:132:0;17305:408:1;53589:132:0;53739:10;53750:5;53739:17;;;;;;;;:::i;:::-;;;;;;;;;53732:24;;53444:320;;;:::o;122280:593::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;122381:30:::1;::::0;;;;122405:4:::1;122381:30;::::0;::::1;809:74:1::0;122381:15:0::1;::::0;::::1;::::0;::::1;::::0;782:18:1;;122381:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;122359:117;;;::::0;::::1;::::0;;17920:2:1;122359:117:0::1;::::0;::::1;17902:21:1::0;;;17939:18;;;17932:30;17998:34;17978:18;;;17971:62;18050:18;;122359:117:0::1;17718:356:1::0;122359:117:0::1;122534:16;::::0;122489:25:::1;::::0;122534:24:::1;::::0;:16:::1;;:22;:24::i;:::-;122489:70;;122570:8;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;122602:8;:17;;;122620:12;24818:10:::0;;24738:98;122620:12:::1;122602:35;::::0;;::::1;::::0;;;;;;5000:42:1;4988:55;;;122602:35:0::1;::::0;::::1;4970:74:1::0;122634:2:0::1;5060:18:1::0;;;5053:34;4943:18;;122602:35:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;122670:8;122654:24;;:12;24818:10:::0;;24738:98;122654:12:::1;:24;;;122650:88;;122695:31;::::0;;;;:17:::1;122713:8;4988:55:1::0;;122695:31:0::1;::::0;::::1;4970:74:1::0;122723:2:0::1;5060:18:1::0;;;5053:34;122695:17:0;::::1;::::0;::::1;::::0;4943:18:1;;122695:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;122650:88;122788:30;::::0;;;;122812:4:::1;122788:30;::::0;::::1;809:74:1::0;122750:69:0::1;::::0;122777:8;;122788:15:::1;::::0;::::1;::::0;::::1;::::0;782:18:1;;122788:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;122750:18;::::0;::::1;::::0;:69;:18:::1;:69::i;:::-;122830:35;::::0;;;;:19:::1;827:55:1::0;;;122830:35:0::1;::::0;::::1;809:74:1::0;122830:19:0;::::1;::::0;::::1;::::0;782:18:1;;122830:35:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;122348:525;122280:593:::0;;:::o;120074:143::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;120189:20;;::::1;::::0;:8:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;30251:326::-:0;30368:7;30409:16;;;:7;:16;;;;;;;;30458:19;30436:110;;;;;;;18281:2:1;30436:110:0;;;18263:21:1;18320:2;18300:18;;;18293:30;18359:34;18339:18;;;18332:62;18430:11;18410:18;;;18403:39;18459:19;;30436:110:0;18079:405:1;29894:295:0;30011:7;30058:19;;;30036:111;;;;;;;18691:2:1;30036:111:0;;;18673:21:1;18730:2;18710:18;;;18703:30;18769:34;18749:18;;;18742:62;18840:12;18820:18;;;18813:40;18870:19;;30036:111:0;18489:406:1;30036:111:0;-1:-1:-1;30165:16:0;;;;;;:9;:16;;;;;;;29894:295::o;115283:738::-;115389:16;60290:8;60035:7;;;;;59964:86;60290:8;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;115454:19:::1;115445:5;:28;;;;115423:132;;;::::0;::::1;::::0;;19102:2:1;115423:132:0::1;::::0;::::1;19084:21:1::0;19141:2;19121:18;;;19114:30;19180:34;19160:18;;;19153:62;19251:24;19231:18;;;19224:52;19293:19;;115423:132:0::1;18900:418:1::0;115423:132:0::1;115569:11;115582::::0;115597:21:::1;:19;:21::i;:::-;115568:50:::0;;-1:-1:-1;115568:50:0;-1:-1:-1;115666:11:0::1;;::::0;::::1;115568:50:::0;115666:11:::1;:::i;:::-;115653:9;:24;;:52;;;;-1:-1:-1::0;115694:11:0::1;;::::0;::::1;:3:::0;:11:::1;:::i;:::-;115681:9;:24;;115653:52;115631:152;;;::::0;::::1;::::0;;13030:2:1;115631:152:0::1;::::0;::::1;13012:21:1::0;13069:2;13049:18;;;13042:30;13108:34;13088:18;;;13081:62;13179:20;13159:18;;;13152:48;13217:19;;115631:152:0::1;12828:414:1::0;115631:152:0::1;115796:25;115838:5;115824:20;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;115824:20:0::1;;115796:48;;115862:9;115857:102;115881:5;115877:9;;:1;:9;115857:102;;;115922:25;24818:10:::0;115090:11:::1;:25::i;115922:::-;115908:8;115917:1;115908:11;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:39;115888:3;::::1;::::0;::::1;:::i;:::-;;;;115857:102;;;;115971:14;:12;:14::i;:::-;116005:8:::0;-1:-1:-1;;;60330:1:0::1;115283:738:::0;;;:::o;119424:73::-;110549:24;69200:16;69211:4;69200:10;:16::i;:::-;119481:8:::1;:6;:8::i;89471:203::-:0;89606:7;89638:18;;;:12;:18;;;;;:28;;89660:5;89638:21;:28::i;:::-;89631:35;89471:203;-1:-1:-1;;;89471:203:0:o;30813:104::-;30869:13;30902:7;30895:14;;;;;:::i;113330:248::-;113417:52;113425:29;;;113393:7;113425:29;;;:21;:29;;;;;;113393:7;;113425:29;113413:93;;-1:-1:-1;113493:1:0;;113330:248;-1:-1:-1;113330:248:0:o;113413:93::-;113525:29;;;;;;;;:21;:29;;;;;;;;:45;;;;;;;;809:74:1;;;;113525:29:0;;;;:37;;782:18:1;;113525:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;32718:187::-;32845:52;24818:10;32878:8;32888;32845:18;:52::i;33960:365::-;34149:41;24818:10;34182:7;34149:18;:41::i;:::-;34127:140;;;;;;;14389:2:1;34127:140:0;;;14371:21:1;14428:2;14408:18;;;14401:30;14467:34;14447:18;;;14440:62;14538:19;14518:18;;;14511:47;14575:19;;34127:140:0;14187:413:1;34127:140:0;34278:39;34292:4;34298:2;34302:7;34311:5;34278:13;:39::i;:::-;33960:365;;;;:::o;121030:494::-;35937:4;35961:16;;;:7;:16;;;;;;121148:13;;35961:30;:16;121179:113;;;;;;;19525:2:1;121179:113:0;;;19507:21:1;19564:2;19544:18;;;19537:30;19603:34;19583:18;;;19576:62;19674:17;19654:18;;;19647:45;19709:19;;121179:113:0;19323:411:1;121179:113:0;121389:8;121420:26;121438:7;121420:17;:26::i;:::-;121469:13;121350:151;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;121305:211;;121030:494;;;:::o;89848:192::-;89973:7;90005:18;;;:12;:18;;;;;:27;;:25;:27::i;117874:200::-;118018:7;;69200:16;118018:7;69200:10;:16::i;:::-;60756:14:::1;60773:8;60035:7:::0;;;;;59964:86;60773:8:::1;60756:25;;60796:9;60792:52;;;60822:10;:8;:10::i;:::-;118050:16:::2;118062:3;118050:11;:16::i;:::-;118043:23;;60870:9:::1;60866:50;;;60896:8;:6;:8::i;:::-;60745:178;117874:200:::0;;;;:::o;72146:190::-;71389:7;71421:12;;;:6;:12;;;;;:22;;;69200:16;69211:4;69200:10;:16::i;:::-;72302:26:::1;72314:4;72320:7;72302:11;:26::i;113974:263::-:0;114156:11;;114056:122;;;;;:21;114092:12;21700:15:1;;114056:122:0;;;21682:34:1;114127:13:0;21752:15:1;;21732:18;;;21725:43;21784:18;;;21777:34;;;;-1:-1:-1;;;;114056:6:0;:21;;;;;;21594:18:1;;114056:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114209:11;;114038:140;;-1:-1:-1;114224:5:0;;114199:21;;114209:11;;114038:140;114199:21;:::i;:::-;114198:31;;;;:::i;:::-;114191:38;;;113974:263;:::o;112919:305::-;112983:7;35961:16;;;:7;:16;;;;;;:30;:16;113003:58;;-1:-1:-1;113048:1:0;;112919:305;-1:-1:-1;112919:305:0:o;113003:58::-;113093:52;113115:29;;;:20;:29;;;;;;;;;;;;;113093:52;;;:21;:52;;;;;;113172:29;;;;;;;;113093:123;;;;;;;809:74:1;;;;113093:52:0;;;;;:60;;782:18:1;;113093:123:0;638:251:1;116760:875:0;116860:16;60290:8;60035:7;;;;;59964:86;60290:8;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;116925:19:::1;116916:5;:28;;116894:132;;;::::0;::::1;::::0;;19102:2:1;116894:132:0::1;::::0;::::1;19084:21:1::0;19141:2;19121:18;;;19114:30;19180:34;19160:18;;;19153:62;19251:24;19231:18;;;19224:52;19293:19;;116894:132:0::1;18900:418:1::0;116894:132:0::1;117039:23;117079:5;117065:11;;:19;;;;:::i;:::-;117039:45:::0;-1:-1:-1;117039:45:0;117119:23:::1;:13;:23;;24818:10:::0;117119:52:::1;::::0;;::::1;::::0;;;;;;13431:42:1;13500:15;;;117119:52:0::1;::::0;::::1;13482:34:1::0;117165:4:0::1;13532:18:1::0;;;13525:43;13394:18;;117119:52:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:88;;117097:188;;;::::0;::::1;::::0;;13970:2:1;117097:188:0::1;::::0;::::1;13952:21:1::0;14009:2;13989:18;;;13982:30;14048:34;14028:18;;;14021:62;14119:20;14099:18;;;14092:48;14157:19;;117097:188:0::1;13768:414:1::0;117097:188:0::1;117298:126;:13;:30;;24818:10:::0;117378:4:::1;117398:15:::0;117298:30:::1;:126::i;:::-;117437:25;117479:5;117465:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;117465:20:0::1;;117437:48;;117503:9;117498:102;117522:5;117518:1;:9;117498:102;;;117563:25;24818:10:::0;115090:11:::1;:25::i;117563:::-;117549:8;117558:1;117549:11;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:39;117529:3;::::1;::::0;::::1;:::i;:::-;;;;117498:102;;;-1:-1:-1::0;117619:8:0;116760:875;-1:-1:-1;;;116760:875:0:o;119633:146::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;-1:-1:-1;119745:11:0::1;:26:::0;119633:146::o;91615:622::-;91672:16;91742:4;91736:11;91808:66;91786:3;91761:128;91936:14;91930:4;91926:25;91919:4;91914:3;91910:14;91903:49;92024:66;92000:4;91995:3;91991:14;91966:139;92146:4;92141:3;92138:1;92131:20;92119:32;-1:-1:-1;;92180:22:0;;;92172:57;;;;;;;22024:2:1;92172:57:0;;;22006:21:1;22063:2;22043:18;;;22036:30;22102:24;22082:18;;;22075:52;22144:18;;92172:57:0;21822:346:1;74413:238:0;69811:4;69840:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;74492:152;;74536:12;;;;:6;:12;;;;;;;;:29;;;;;;;;;;:36;;;;74568:4;74536:36;;;74619:12;24818:10;;24738:98;74619:12;74592:40;;74610:7;74592:40;;74604:4;74592:40;;;;;;;;;;74413:238;;:::o;83077:175::-;83165:4;83194:50;83199:3;83219:23;;;83194:4;:50::i;88582:290::-;88712:4;88754:57;;;88769:42;88754:57;;:110;;;88828:36;88852:11;88828:23;:36::i;40159:174::-;40234:24;;;;:15;:24;;;;;:29;;;;;;;;;;;;;:24;;40288:23;40234:24;40288:14;:23::i;:::-;40279:46;;;;;;;;;;;;40159:174;;:::o;70181:105::-;70248:30;70259:4;24818:10;70248;:30::i;61326:120::-;60035:7;;;;60559:41;;;;;;;22375:2:1;60559:41:0;;;22357:21:1;22414:2;22394:18;;;22387:30;22453:22;22433:18;;;22426:50;22493:18;;60559:41:0;22173:344:1;60559:41:0;61385:7:::1;:15:::0;;;::::1;::::0;;61416:22:::1;24818:10:::0;61425:12:::1;61416:22;::::0;839:42:1;827:55;;;809:74;;797:2;782:18;61416:22:0::1;;;;;;;61326:120::o:0;118856:515::-;118916:7;118936:14;118953:13;53342:10;:17;;53254:113;118953:13;118936:30;-1:-1:-1;118999:10:0;118985;118936:30;118994:1;118985:10;:::i;:::-;:24;;118977:51;;;;;;;22857:2:1;118977:51:0;;;22839:21:1;22896:2;22876:18;;;22869:30;22935:16;22915:18;;;22908:44;22969:18;;118977:51:0;22655:338:1;118977:51:0;119041:15;119059:10;:6;119068:1;119059:10;:::i;:::-;119041:28;;119082:39;119108:7;119117:3;119082:25;:39::i;:::-;119134:23;119144:3;119149:7;119134:9;:23::i;:::-;119231:52;119253:29;;;:20;:29;;;;;;;;;;;;;119231:52;;:21;:52;;;;;;;119170:143;;119201:7;;119231:52;119299:3;119170:16;:143::i;61067:118::-;60035:7;;;;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;61127:7:::1;:14:::0;;;::::1;61137:4;61127:14;::::0;;61157:20:::1;61164:12;24818:10:::0;;24738:98;114245:289;114326:12;114340;114370:15;114388:13;:11;:13::i;:::-;114370:31;-1:-1:-1;114438:5:0;114420:14;114370:31;114430:4;114420:14;:::i;:::-;114419:24;;;;:::i;:::-;114412:31;-1:-1:-1;114501:5:0;114482:15;:7;114492:5;114482:15;:::i;:::-;114481:25;;;;:::i;:::-;114474:32;;114359:175;114245:289;;:::o;114542:79::-;114586:27;;;;;:13;114600:12;827:55:1;;114586:27:0;;;809:74:1;114586:6:0;:13;;;;782:18:1;;114586:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12914:285;13112:68;;21631:42:1;21700:15;;;13112:68:0;;;21682:34:1;21752:15;;21732:18;;;21725:43;21784:18;;;21777:34;;;13058:133:0;;13092:5;;13135:27;;21594:18:1;;13112:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13058:19;:133::i;36166:452::-;36295:4;35961:16;;;:7;:16;;;;;;:30;:16;36317:110;;;;;;;23200:2:1;36317:110:0;;;23182:21:1;23239:2;23219:18;;;23212:30;23278:34;23258:18;;;23251:62;23349:14;23329:18;;;23322:42;23381:19;;36317:110:0;22998:408:1;36317:110:0;36438:13;36454:23;36469:7;36454:14;:23::i;:::-;36438:39;;36507:5;36496:16;;:7;:16;;;:64;;;;36553:7;36529:31;;:20;36541:7;36529:11;:20::i;:::-;:31;;;36496:64;:113;;;-1:-1:-1;33147:25:0;;;;33118:4;33147:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;36577:32;36488:122;36166:452;-1:-1:-1;;;;36166:452:0:o;39379:662::-;39552:4;39525:31;;:23;39540:7;39525:14;:23::i;:::-;:31;;;39503:118;;;;;;;23613:2:1;39503:118:0;;;23595:21:1;23652:2;23632:18;;;23625:30;23691:34;23671:18;;;23664:62;23762:7;23742:18;;;23735:35;23787:19;;39503:118:0;23411:401:1;39503:118:0;39640:16;;;39632:65;;;;;;;24019:2:1;39632:65:0;;;24001:21:1;24058:2;24038:18;;;24031:30;24097:34;24077:18;;;24070:62;24168:6;24148:18;;;24141:34;24192:19;;39632:65:0;23817:400:1;39632:65:0;39710:39;39731:4;39737:2;39741:7;39710:20;:39::i;:::-;39814:29;39831:1;39835:7;39814:8;:29::i;:::-;39856:15;;;;;;;:9;:15;;;;;:20;;39875:1;;39856:15;:20;;39875:1;;39856:20;:::i;:::-;;;;-1:-1:-1;;39887:13:0;;;;;;;:9;:13;;;;;:18;;39904:1;;39887:13;:18;;39904:1;;39887:18;:::i;:::-;;;;-1:-1:-1;;39916:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;;39955:27;;39916:16;;39955:27;;;;;;;39995:38;40015:4;40021:2;40025:7;39995:19;:38::i;90133:201::-;90253:31;90270:4;90276:7;90253:16;:31::i;:::-;90295:18;;;;:12;:18;;;;;:31;;90318:7;90295:22;:31::i;90428:206::-;90549:32;90567:4;90573:7;90549:17;:32::i;:::-;90592:18;;;;:12;:18;;;;;:34;;90618:7;90592:25;:34::i;120354:321::-;120448:13;120499:168;120664:2;120574:22;:11;:20;:22::i;:::-;120598:18;:7;:16;:18::i;:::-;120557:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;120525:111;;120557:60;120525:111;;;;;120499:164;:168::i;12658:248::-;12829:58;;5000:42:1;4988:55;;12829:58:0;;;4970:74:1;5060:18;;;5053:34;;;12775:123:0;;12809:5;;12852:23;;4943:18:1;;12829:58:0;4796:297:1;84451:190:0;84552:7;84608:22;84612:3;84624:5;84608:3;:22::i;40475:315::-;40630:8;40621:17;;:5;:17;;;;40613:55;;;;;;;25029:2:1;40613:55:0;;;25011:21:1;25068:2;25048:18;;;25041:30;25107:27;25087:18;;;25080:55;25152:18;;40613:55:0;24827:349:1;40613:55:0;40679:25;;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;;;;;;;;;;;;40741:41;;586::1;;;40741::0;;559:18:1;40741:41:0;;;;;;;40475:315;;;:::o;35207:352::-;35364:28;35374:4;35380:2;35384:7;35364:9;:28::i;:::-;35425:48;35448:4;35454:2;35458:7;35467:5;35425:22;:48::i;:::-;35403:148;;;;;;;25383:2:1;35403:148:0;;;25365:21:1;25422:2;25402:18;;;25395:30;25461:34;25441:18;;;25434:62;25532:20;25512:18;;;25505:48;25570:19;;35403:148:0;25181:414:1;83980:117:0;84043:7;84070:19;84078:3;79212:18;;79129:109;76786:414;76849:4;79011:19;;;:12;;;:19;;;;;;76866:327;;-1:-1:-1;76909:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;77092:18;;77070:19;;;:12;;;:19;;;;;;:40;;;;77125:11;;76866:327;-1:-1:-1;77176:5:0;77169:12;;69308:280;69438:4;69480:47;;;69495:32;69480:47;;:100;;;69544:36;69568:11;69544:23;:36::i;70576:505::-;69811:4;69840:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;70660:414;;70853:41;70881:7;70853:41;;70891:2;70853:19;:41::i;:::-;70967:38;70995:4;71002:2;70967:19;:38::i;:::-;70758:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;70704:358;;;;;;;;:::i;112014:787::-;112122:54;112130:31;;;112174:1;112130:31;;;:21;:31;;;;;;;112118:623;;112262:16;;:24;;:16;;:22;:24::i;:::-;112193:31;;;;;;;;:21;:31;;;;;;:108;;;;;;;;;;;;;;112316:44;;;;;;;:42;;:44;;;;;112193:31;112316:44;;;;;;112193:31;:108;112316:44;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;112375:31:0;;;;;;;;:21;:31;;;;;;;;112442:19;;112375:122;;;;;112442:19;;;112375:122;;;4970:74:1;112375:31:0;5060:18:1;;;5053:34;112375:31:0;;;;:40;;4943:18:1;;112375:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;112512:31:0;;;;;;;;:21;:31;;;;;;;;:53;;;;;;;;4970:74:1;;;;112512:31:0;5060:18:1;;;5053:34;112512:31:0;;;;:40;;4943:18:1;;112512:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;112587:142:0;;;;112629:31;;;;:21;:31;;;;;;;112587:142;;;;-1:-1:-1;112680:7:0;;112629:31;;112587:142;;112629:31;112587:142;112118:623;112753:29;;;;:20;:29;;;;;;:40;;;;;;;;;;;;;;112014:787::o;36960:110::-;37036:26;37046:2;37050:7;37036:26;;;;;;;;;;;;:9;:26::i;48248:427::-;47077:5;48414:33;;;;;48392:125;;;;;;;26903:2:1;48392:125:0;;;26885:21:1;26942:2;26922:18;;;26915:30;26981:34;26961:18;;;26954:62;27052:12;27032:18;;;27025:40;27082:19;;48392:125:0;26701:406:1;48392:125:0;48536:22;;;48528:62;;;;;;;27314:2:1;48528:62:0;;;27296:21:1;27353:2;27333:18;;;27326:30;27392:29;27372:18;;;27365:57;27439:18;;48528:62:0;27112:351:1;48528:62:0;48632:35;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48603:26:0;;;:17;:26;;;;;;:64;;;;;;;;;;;;;;48248:427::o;15625:802::-;16049:23;16075:106;16117:4;16075:106;;;;;;;;;;;;;;;;;16083:5;16075:27;;;;:106;;;;;:::i;:::-;16196:17;;16049:132;;-1:-1:-1;16196:21:0;16192:228;;16311:10;16300:30;;;;;;;;;;;;:::i;:::-;16274:134;;;;;;;27920:2:1;16274:134:0;;;27902:21:1;27959:2;27939:18;;;27932:30;27998:34;27978:18;;;27971:62;28069:12;28049:18;;;28042:40;28099:19;;16274:134:0;27718:406:1;122960:239:0;123146:45;123173:4;123179:2;123183:7;123146:26;:45::i;123207:385::-;123387:1;123346:29;;;:20;:29;;;;;;:43;:29;:43;123342:141;;123406:52;123428:29;;;:20;:29;;;;;;;;;;;;;123406:52;;:21;:52;;;;;;;:65;;;;;;;:52;;;:63;;:65;;;;;;;;;;:52;;:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123342:141;123495:19;;;;;;;;;;;:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74783:239;69811:4;69840:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;74863:152;;;74938:5;74906:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;:37;;;;;;74963:40;24818:10;;74906:12;;74963:40;;74938:5;74963:40;74783:239;;:::o;83428:181::-;83519:4;83548:53;83556:3;83576:23;;;83548:7;:53::i;25287:723::-;25343:13;25564:10;25560:53;;-1:-1:-1;;25591:10:0;;;;;;;;;;;;;;;;;;25287:723::o;25560:53::-;25638:5;25623:12;25679:78;25686:9;;25679:78;;25712:8;;;;:::i;:::-;;-1:-1:-1;25735:10:0;;-1:-1:-1;25743:2:0;25735:10;;:::i;:::-;;;25679:78;;;25767:19;25799:6;25789:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25789:17:0;;25767:39;;25817:154;25824:10;;25817:154;;25851:11;25861:1;25851:11;;:::i;:::-;;-1:-1:-1;25920:10:0;25928:2;25920:5;:10;:::i;:::-;25907:24;;:2;:24;:::i;:::-;25894:39;;25877:6;25884;25877:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;25948:11:0;25957:2;25948:11;;:::i;:::-;;;25817:154;;26588:483;26690:13;26721:19;26753:10;26757:6;26753:1;:10;:::i;:::-;:14;;26766:1;26753:14;:::i;:::-;26743:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26743:25:0;;26721:47;;26779:15;:6;26786:1;26779:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;;26805;:6;26812:1;26805:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;-1:-1:-1;26836:9:0;26848:10;26852:6;26848:1;:10;:::i;:::-;:14;;26861:1;26848:14;:::i;:::-;26836:26;;26831:135;26868:1;26864;:5;26831:135;;;26903:12;26916:5;26924:3;26916:11;26903:25;;;;;;;:::i;:::-;;;;26891:6;26898:1;26891:9;;;;;;;;:::i;:::-;;;;:37;;;;;;;;;;-1:-1:-1;26953:1:0;26943:11;;;;;26871:3;;;:::i;:::-;;;26831:135;;;-1:-1:-1;26984:10:0;;26976:55;;;;;;;28649:2:1;26976:55:0;;;28631:21:1;;;28668:18;;;28661:30;28727:34;28707:18;;;28700:62;28779:18;;26976:55:0;28447:356:1;79592:152:0;79686:7;79718:3;:11;;79730:5;79718:18;;;;;;;;:::i;:::-;;;;;;;;;79711:25;;79592:152;;;;:::o;41355:980::-;41510:4;41531:13;;;4553:19;:23;41527:801;;41584:175;;;;;:36;;;;;;:175;;24818:10;;41678:4;;41705:7;;41735:5;;41584:175;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41584:175:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;41563:710;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41942:13:0;;41938:320;;41985:108;;;;;25383:2:1;41985:108:0;;;25365:21:1;25422:2;25402:18;;;25395:30;25461:34;25441:18;;;25434:62;25532:20;25512:18;;;25505:48;25570:19;;41985:108:0;25181:414:1;41938:320:0;42208:6;42202:13;42193:6;42189:2;42185:15;42178:38;41563:710;41823:51;;41833:41;41823:51;;-1:-1:-1;41816:58:0;;41527:801;-1:-1:-1;42312:4:0;41355:980;;;;;;:::o;49920:220::-;50067:4;50096:36;50120:11;50096:23;:36::i;37297:321::-;37427:18;37433:2;37437:7;37427:5;:18::i;:::-;37478:54;37509:1;37513:2;37517:7;37526:5;37478:22;:54::i;:::-;37456:154;;;;;;;25383:2:1;37456:154:0;;;25365:21:1;25422:2;25402:18;;;25395:30;25461:34;25441:18;;;25434:62;25532:20;25512:18;;;25505:48;25570:19;;37456:154:0;25181:414:1;7100:229:0;7237:12;7269:52;7291:6;7299:4;7305:1;7308:12;7269:21;:52::i;62097:275::-;62241:45;62268:4;62274:2;62278:7;62241:26;:45::i;:::-;60035:7;;;;62307:9;62299:65;;;;;;;29781:2:1;62299:65:0;;;29763:21:1;29820:2;29800:18;;;29793:30;29859:34;29839:18;;;29832:62;29930:13;29910:18;;;29903:41;29961:19;;62299:65:0;29579:407:1;77376:1420:0;77442:4;77581:19;;;:12;;;:19;;;;;;77617:15;;77613:1176;;77992:21;78016:14;78029:1;78016:10;:14;:::i;:::-;78065:18;;77992:38;;-1:-1:-1;78045:17:0;;78065:22;;78086:1;;78065:22;:::i;:::-;78045:42;;78121:13;78108:9;:26;78104:405;;78155:17;78175:3;:11;;78187:9;78175:22;;;;;;;;:::i;:::-;;;;;;;;;78155:42;;78329:9;78300:3;:11;;78312:13;78300:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;78414:23;;;:12;;;:23;;;;;:36;;;78104:405;78590:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;78685:3;:12;;:19;78698:5;78685:19;;;;;;;;;;;78678:26;;;78728:4;78721:11;;;;;;;77613:1176;78772:5;78765:12;;;;;52451:300;52598:4;52640:50;;;52655:35;52640:50;;:103;;;52707:36;52731:11;52707:23;:36::i;37954:439::-;38034:16;;;38026:61;;;;;;;30382:2:1;38026:61:0;;;30364:21:1;;;30401:18;;;30394:30;30460:34;30440:18;;;30433:62;30512:18;;38026:61:0;30180:356:1;38026:61:0;35937:4;35961:16;;;:7;:16;;;;;;:30;:16;:30;38098:58;;;;;;;30743:2:1;38098:58:0;;;30725:21:1;30782:2;30762:18;;;30755:30;30821;30801:18;;;30794:58;30869:18;;38098:58:0;30541:352:1;38098:58:0;38169:45;38198:1;38202:2;38206:7;38169:20;:45::i;:::-;38227:13;;;;;;;:9;:13;;;;;:18;;38244:1;;38227:13;:18;;38244:1;;38227:18;:::i;:::-;;;;-1:-1:-1;;38256:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;38295:33;;38256:16;;;38295:33;;38256:16;;38295:33;38341:44;38369:1;38373:2;38377:7;38341:19;:44::i;8316:571::-;8486:12;8558:5;8533:21;:30;;8511:118;;;;;;;31100:2:1;8511:118:0;;;31082:21:1;31139:2;31119:18;;;31112:30;31178:34;31158:18;;;31151:62;31249:8;31229:18;;;31222:36;31275:19;;8511:118:0;30898:402:1;8511:118:0;4553:19;;;;8640:60;;;;;;;31507:2:1;8640:60:0;;;31489:21:1;31546:2;31526:18;;;31519:30;31585:31;31565:18;;;31558:59;31634:18;;8640:60:0;31305:353:1;8640:60:0;8714:12;8728:23;8755:6;:11;;8774:5;8795:4;8755:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8713:97;;;;8828:51;8845:7;8854:10;8866:12;8828:16;:51::i;:::-;8821:58;8316:571;-1:-1:-1;;;;;;;8316:571:0:o;54377:589::-;54583:18;;;54579:187;;54618:40;54650:7;55793:10;:17;;55766:24;;;;:15;:24;;;;;:44;;;55821:24;;;;;;;;;;;;55689:164;54618:40;54579:187;;;54688:2;54680:10;;:4;:10;;;54676:90;;54707:47;54740:4;54746:7;54707:32;:47::i;:::-;54780:16;;;54776:183;;54813:45;54850:7;54813:36;:45::i;54776:183::-;54886:4;54880:10;;:2;:10;;;54876:83;;54907:40;54935:2;54939:7;54907:27;:40::i;29475:355::-;29622:4;29664:40;;;29679:25;29664:40;;:105;;-1:-1:-1;29721:48:0;;;29736:33;29721:48;29664:105;:158;;;;29786:36;29810:11;29786:23;:36::i;11276:712::-;11426:12;11455:7;11451:530;;;-1:-1:-1;11486:10:0;11479:17;;11451:530;11600:17;;:21;11596:374;;11798:10;11792:17;11859:15;11846:10;11842:2;11838:19;11831:44;11596:374;11941:12;11934:20;;;;;;;;;;;:::i;56480:1002::-;56760:22;56810:1;56785:22;56802:4;56785:16;:22::i;:::-;:26;;;;:::i;:::-;56822:18;56843:26;;;:17;:26;;;;;;56760:51;;-1:-1:-1;56976:28:0;;;56972:328;;57043:18;;;57021:19;57043:18;;;:12;:18;;;;;;;;:34;;;;;;;;;57094:30;;;;;;:44;;;57211:30;;:17;:30;;;;;:43;;;56972:328;-1:-1:-1;57396:26:0;;;;:17;:26;;;;;;;;57389:33;;;57440:18;;;;;;:12;:18;;;;;:34;;;;;;;57433:41;56480:1002::o;57777:1079::-;58055:10;:17;58030:22;;58055:21;;58075:1;;58055:21;:::i;:::-;58087:18;58108:24;;;:15;:24;;;;;;58481:10;:26;;58030:46;;-1:-1:-1;58108:24:0;;58030:46;;58481:26;;;;;;:::i;:::-;;;;;;;;;58459:48;;58545:11;58520:10;58531;58520:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;58625:28;;;:15;:28;;;;;;;:41;;;58797:24;;;;;58790:31;58832:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;57848:1008;;;57777:1079;:::o;55267:221::-;55352:14;55369:20;55386:2;55369:16;:20::i;:::-;55400:16;;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;55445:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;55267:221:0:o;45858:291::-;46005:4;46047:41;;;46062:26;46047:41;;:94;;-1:-1:-1;28085:25:0;28070:40;;;;46105:36;27911:207;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:177:1;99:66;92:5;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;894:258::-;966:1;976:113;990:6;987:1;984:13;976:113;;;1066:11;;;1060:18;1047:11;;;1040:39;1012:2;1005:10;976:113;;;1107:6;1104:1;1101:13;1098:48;;;-1:-1:-1;;1142:1:1;1124:16;;1117:27;894:258::o;1157:317::-;1199:3;1237:5;1231:12;1264:6;1259:3;1252:19;1280:63;1336:6;1329:4;1324:3;1320:14;1313:4;1306:5;1302:16;1280:63;:::i;:::-;1388:2;1376:15;1393:66;1372:88;1363:98;;;;1463:4;1359:109;;1157:317;-1:-1:-1;;1157:317:1:o;1479:220::-;1628:2;1617:9;1610:21;1591:4;1648:45;1689:2;1678:9;1674:18;1666:6;1648:45;:::i;1704:180::-;1763:6;1816:2;1804:9;1795:7;1791:23;1787:32;1784:52;;;1832:1;1829;1822:12;1784:52;-1:-1:-1;1855:23:1;;1704:180;-1:-1:-1;1704:180:1:o;2120:154::-;2206:42;2199:5;2195:54;2188:5;2185:65;2175:93;;2264:1;2261;2254:12;2279:315;2347:6;2355;2408:2;2396:9;2387:7;2383:23;2379:32;2376:52;;;2424:1;2421;2414:12;2376:52;2463:9;2450:23;2482:31;2507:5;2482:31;:::i;:::-;2532:5;2584:2;2569:18;;;;2556:32;;-1:-1:-1;;;2279:315:1:o;2599:632::-;2770:2;2822:21;;;2892:13;;2795:18;;;2914:22;;;2741:4;;2770:2;2993:15;;;;2967:2;2952:18;;;2741:4;3036:169;3050:6;3047:1;3044:13;3036:169;;;3111:13;;3099:26;;3180:15;;;;3145:12;;;;3072:1;3065:9;3036:169;;;-1:-1:-1;3222:3:1;;2599:632;-1:-1:-1;;;;;;2599:632:1:o;3236:292::-;3294:6;3347:2;3335:9;3326:7;3322:23;3318:32;3315:52;;;3363:1;3360;3353:12;3315:52;3402:9;3389:23;3452:26;3445:5;3441:38;3434:5;3431:49;3421:77;;3494:1;3491;3484:12;3715:456;3792:6;3800;3808;3861:2;3849:9;3840:7;3836:23;3832:32;3829:52;;;3877:1;3874;3867:12;3829:52;3916:9;3903:23;3935:31;3960:5;3935:31;:::i;:::-;3985:5;-1:-1:-1;4042:2:1;4027:18;;4014:32;4055:33;4014:32;4055:33;:::i;:::-;3715:456;;4107:7;;-1:-1:-1;;;4161:2:1;4146:18;;;;4133:32;;3715:456::o;4543:248::-;4611:6;4619;4672:2;4660:9;4651:7;4647:23;4643:32;4640:52;;;4688:1;4685;4678:12;4640:52;-1:-1:-1;;4711:23:1;;;4781:2;4766:18;;;4753:32;;-1:-1:-1;4543:248:1:o;5098:315::-;5166:6;5174;5227:2;5215:9;5206:7;5202:23;5198:32;5195:52;;;5243:1;5240;5233:12;5195:52;5279:9;5266:23;5256:33;;5339:2;5328:9;5324:18;5311:32;5352:31;5377:5;5352:31;:::i;:::-;5402:5;5392:15;;;5098:315;;;;;:::o;5678:247::-;5737:6;5790:2;5778:9;5769:7;5765:23;5761:32;5758:52;;;5806:1;5803;5796:12;5758:52;5845:9;5832:23;5864:31;5889:5;5864:31;:::i;6195:184::-;6247:77;6244:1;6237:88;6344:4;6341:1;6334:15;6368:4;6365:1;6358:15;6384:691;6449:5;6479:18;6520:2;6512:6;6509:14;6506:40;;;6526:18;;:::i;:::-;6660:2;6654:9;6726:2;6714:15;;6565:66;6710:24;;;6736:2;6706:33;6702:42;6690:55;;;6760:18;;;6780:22;;;6757:46;6754:72;;;6806:18;;:::i;:::-;6846:10;6842:2;6835:22;6875:6;6866:15;;6905:6;6897;6890:22;6945:3;6936:6;6931:3;6927:16;6924:25;6921:45;;;6962:1;6959;6952:12;6921:45;7012:6;7007:3;7000:4;6992:6;6988:17;6975:44;7067:1;7060:4;7051:6;7043;7039:19;7035:30;7028:41;;;;6384:691;;;;;:::o;7080:451::-;7149:6;7202:2;7190:9;7181:7;7177:23;7173:32;7170:52;;;7218:1;7215;7208:12;7170:52;7258:9;7245:23;7291:18;7283:6;7280:30;7277:50;;;7323:1;7320;7313:12;7277:50;7346:22;;7399:4;7391:13;;7387:27;-1:-1:-1;7377:55:1;;7428:1;7425;7418:12;7377:55;7451:74;7517:7;7512:2;7499:16;7494:2;7490;7486:11;7451:74;:::i;7536:269::-;7593:6;7646:2;7634:9;7625:7;7621:23;7617:32;7614:52;;;7662:1;7659;7652:12;7614:52;7701:9;7688:23;7751:4;7744:5;7740:16;7733:5;7730:27;7720:55;;7771:1;7768;7761:12;8520:118;8606:5;8599:13;8592:21;8585:5;8582:32;8572:60;;8628:1;8625;8618:12;8643:382;8708:6;8716;8769:2;8757:9;8748:7;8744:23;8740:32;8737:52;;;8785:1;8782;8775:12;8737:52;8824:9;8811:23;8843:31;8868:5;8843:31;:::i;:::-;8893:5;-1:-1:-1;8950:2:1;8935:18;;8922:32;8963:30;8922:32;8963:30;:::i;9030:795::-;9125:6;9133;9141;9149;9202:3;9190:9;9181:7;9177:23;9173:33;9170:53;;;9219:1;9216;9209:12;9170:53;9258:9;9245:23;9277:31;9302:5;9277:31;:::i;:::-;9327:5;-1:-1:-1;9384:2:1;9369:18;;9356:32;9397:33;9356:32;9397:33;:::i;:::-;9449:7;-1:-1:-1;9503:2:1;9488:18;;9475:32;;-1:-1:-1;9558:2:1;9543:18;;9530:32;9585:18;9574:30;;9571:50;;;9617:1;9614;9607:12;9571:50;9640:22;;9693:4;9685:13;;9681:27;-1:-1:-1;9671:55:1;;9722:1;9719;9712:12;9671:55;9745:74;9811:7;9806:2;9793:16;9788:2;9784;9780:11;9745:74;:::i;:::-;9735:84;;;9030:795;;;;;;;:::o;9830:388::-;9898:6;9906;9959:2;9947:9;9938:7;9934:23;9930:32;9927:52;;;9975:1;9972;9965:12;9927:52;10014:9;10001:23;10033:31;10058:5;10033:31;:::i;:::-;10083:5;-1:-1:-1;10140:2:1;10125:18;;10112:32;10153:33;10112:32;10153:33;:::i;10223:437::-;10302:1;10298:12;;;;10345;;;10366:61;;10420:4;10412:6;10408:17;10398:27;;10366:61;10473:2;10465:6;10462:14;10442:18;10439:38;10436:218;;;10510:77;10507:1;10500:88;10611:4;10608:1;10601:15;10639:4;10636:1;10629:15;11905:184;11957:77;11954:1;11947:88;12054:4;12051:1;12044:15;12078:4;12075:1;12068:15;12094:184;12146:77;12143:1;12136:88;12243:4;12240:1;12233:15;12267:4;12264:1;12257:15;12283:195;12322:3;12353:66;12346:5;12343:77;12340:103;;;12423:18;;:::i;:::-;-1:-1:-1;12470:1:1;12459:13;;12283:195::o;13579:184::-;13649:6;13702:2;13690:9;13681:7;13677:23;13673:32;13670:52;;;13718:1;13715;13708:12;13670:52;-1:-1:-1;13741:16:1;;13579:184;-1:-1:-1;13579:184:1:o;14605:228::-;14645:7;14771:1;14703:66;14699:74;14696:1;14693:81;14688:1;14681:9;14674:17;14670:105;14667:131;;;14778:18;;:::i;:::-;-1:-1:-1;14818:9:1;;14605:228::o;14838:184::-;14890:77;14887:1;14880:88;14987:4;14984:1;14977:15;15011:4;15008:1;15001:15;15027:120;15067:1;15093;15083:35;;15098:18;;:::i;:::-;-1:-1:-1;15132:9:1;;15027:120::o;19865:1088::-;19950:12;;19915:3;;20005:1;20025:18;;;;20078;;;;20105:61;;20159:4;20151:6;20147:17;20137:27;;20105:61;20185:2;20233;20225:6;20222:14;20202:18;20199:38;20196:218;;;20270:77;20267:1;20260:88;20371:4;20368:1;20361:15;20399:4;20396:1;20389:15;20196:218;20430:18;20457:162;;;;20633:1;20628:319;;;;20423:524;;20457:162;20505:66;20494:9;20490:82;20485:3;20478:95;20602:6;20597:3;20593:16;20586:23;;20457:162;;20628:319;19812:1;19805:14;;;19849:4;19836:18;;20722:1;20736:165;20750:6;20747:1;20744:13;20736:165;;;20828:14;;20815:11;;;20808:35;20871:16;;;;20765:10;;20736:165;;;20740:3;;20930:6;20925:3;20921:16;20914:23;;20423:524;;;;;;;19865:1088;;;;:::o;20958:456::-;21179:3;21207:38;21241:3;21233:6;21207:38;:::i;:::-;21274:6;21268:13;21290:52;21335:6;21331:2;21324:4;21316:6;21312:17;21290:52;:::i;:::-;21358:50;21400:6;21396:2;21392:15;21384:6;21358:50;:::i;22522:128::-;22562:3;22593:1;22589:6;22586:1;22583:13;22580:39;;;22599:18;;:::i;:::-;-1:-1:-1;22635:9:1;;22522:128::o;24222:125::-;24262:4;24290:1;24287;24284:8;24281:34;;;24295:18;;:::i;:::-;-1:-1:-1;24332:9:1;;24222:125::o;24352:470::-;24531:3;24569:6;24563:13;24585:53;24631:6;24626:3;24619:4;24611:6;24607:17;24585:53;:::i;:::-;24701:13;;24660:16;;;;24723:57;24701:13;24660:16;24757:4;24745:17;;24723:57;:::i;:::-;24796:20;;24352:470;-1:-1:-1;;;;24352:470:1:o;25600:786::-;26011:25;26006:3;25999:38;25981:3;26066:6;26060:13;26082:62;26137:6;26132:2;26127:3;26123:12;26116:4;26108:6;26104:17;26082:62;:::i;:::-;26208:19;26203:2;26163:16;;;26195:11;;;26188:40;26253:13;;26275:63;26253:13;26324:2;26316:11;;26309:4;26297:17;;26275:63;:::i;:::-;26358:17;26377:2;26354:26;;25600:786;-1:-1:-1;;;;25600:786:1:o;27468:245::-;27535:6;27588:2;27576:9;27567:7;27563:23;27559:32;27556:52;;;27604:1;27601;27594:12;27556:52;27636:9;27630:16;27655:28;27677:5;27655:28;:::i;28129:112::-;28161:1;28187;28177:35;;28192:18;;:::i;:::-;-1:-1:-1;28226:9:1;;28129:112::o;28246:196::-;28285:3;28313:5;28303:39;;28322:18;;:::i;:::-;-1:-1:-1;28369:66:1;28358:78;;28246:196::o;28808:512::-;29002:4;29031:42;29112:2;29104:6;29100:15;29089:9;29082:34;29164:2;29156:6;29152:15;29147:2;29136:9;29132:18;29125:43;;29204:6;29199:2;29188:9;29184:18;29177:34;29247:3;29242:2;29231:9;29227:18;29220:31;29268:46;29309:3;29298:9;29294:19;29286:6;29268:46;:::i;:::-;29260:54;28808:512;-1:-1:-1;;;;;;28808:512:1:o;29325:249::-;29394:6;29447:2;29435:9;29426:7;29422:23;29418:32;29415:52;;;29463:1;29460;29453:12;29415:52;29495:9;29489:16;29514:30;29538:5;29514:30;:::i;29991:184::-;30043:77;30040:1;30033:88;30140:4;30137:1;30130:15;30164:4;30161:1;30154:15;31663:274;31792:3;31830:6;31824:13;31846:53;31892:6;31887:3;31880:4;31872:6;31868:17;31846:53;:::i;:::-;31915:16;;;;;31663:274;-1:-1:-1;;31663:274:1:o
Swarm Source
ipfs://8d2e5667d706f0318413a45098f3f617b56728a8b5ceb6eb2023c85f6f56ba62
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.