Address Details
contract
token
0x0F85Ddd2B142Ea747761b5143c002526e4b1Fa41
- Token
- GANG ($G)
- Creator
- 0x9f745c–0a32ee at 0x2213ec–c6eb1a
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- 214 Transactions
- Transfers
- 280 Transfers
- Gas Used
- 36,400,221
- Last Balance Update
- 15943380
Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- ChinchillaGANGstaking
- Optimization enabled
- false
- Compiler version
- v0.8.14+commit.80d49f37
- EVM Version
- london
- Verified at
- 2022-06-09T07:39:20.627124Z
contracts/ChinChillaGangStaking.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; contract ChinchillaGANGstaking is Ownable, IERC721Receiver, ERC20{ struct Staker{ address staker; uint256[] tokenIds; uint256[] timestamps; } IERC721 public parent; Staker[] stakers; uint256 maxSupply = 1000000000000; uint256 timeOfReward; uint256 rewardPerDay; constructor( address _NFTcontract, uint256 _rewardPerDay, uint256 _timeOfReward ) ERC20("GANG", "$G"){ parent = IERC721(_NFTcontract); _mint( msg.sender,10000000000); rewardPerDay = _rewardPerDay; timeOfReward = _timeOfReward; } function stake(uint256 tokenId) public { require(totalSupply() < maxSupply, "It's not possible to stake anymore"); parent.safeTransferFrom(msg.sender, address(this), tokenId, "0x00"); } function addToExistingStake(address _user, uint256 _tokenId) internal returns(bool){ (bool found,uint256 position) = isStakeholder(_user); if(found){ stakers[position].tokenIds.push(_tokenId); stakers[position].timestamps.push(block.timestamp); } return found; } function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external override returns (bytes4){ if(!addToExistingStake(from,tokenId)){ uint256[] memory auxVectorId = new uint256[](1); uint256[] memory auxVectorTs = new uint256[](1); auxVectorId[0] = tokenId; auxVectorTs[0] = block.timestamp; Staker memory newStaker = Staker(from,auxVectorId,auxVectorTs); stakers.push(newStaker); } return this.onERC721Received.selector; } function calculateReward(uint256 position) internal returns(uint256){ uint256 calculated_reward = 0; for(uint256 i = 0; i < stakers[position].tokenIds.length; i++){ if((block.timestamp - stakers[position].timestamps[i]) / timeOfReward >= 1){ calculated_reward += ((block.timestamp - stakers[position].timestamps[i]) / timeOfReward) * rewardPerDay; stakers[position].timestamps[i] = block.timestamp; } } require(calculated_reward > 0, "You can withdraw only after 1 day"); require(totalSupply() < maxSupply, "You can't earn tokens anymore"); return calculated_reward; } function calculateRewardIntern(uint256 position) private returns(uint256){ uint256 calculated_reward = 0; for(uint256 i = 0; i < stakers[position].tokenIds.length; i++){ if((block.timestamp - stakers[position].timestamps[i]) / timeOfReward >= 1){ calculated_reward += ((block.timestamp - stakers[position].timestamps[i]) / timeOfReward) * rewardPerDay; stakers[position].timestamps[i] = block.timestamp; } } require(totalSupply() < maxSupply, "You can't earn tokens anymore"); return calculated_reward; } function claim() public{ (bool found,uint256 position) = isStakeholder(msg.sender); require(found, "You're not a stakeholder"); uint256 reward = calculateReward(position); _mint(msg.sender,reward); } function isStakeholder(address _user) public view returns(bool,uint256){ for(uint256 i = 0; i < stakers.length; i++) if(stakers[i].staker == _user) return (true,i); return (false,0); } function checkStakeholder(address _user) internal view returns(bool){ for(uint256 i = 0; i < stakers.length; i++) if(stakers[i].staker == _user) return true; return false; } function unlockNFTs() public onlyOwner{ for(uint256 i = 0; i < stakers.length; i++){ for(uint256 j = 0; j < stakers[i].tokenIds.length; j++){ parent.safeTransferFrom(address(this), stakers[i].staker, stakers[i].tokenIds[j], "0x00"); } delete stakers[i].tokenIds; delete stakers[i].timestamps; } } function retrieveAll() public{ (bool found,uint256 position) = isStakeholder(msg.sender); require(found, "You're not a stakeholder"); uint256 reward = calculateRewardIntern(position); _mint(msg.sender,reward); for(uint256 i = 0; i < stakers[position].tokenIds.length; i++){ parent.safeTransferFrom(address(this), msg.sender, stakers[position].tokenIds[i], "0x00"); } delete stakers[position].tokenIds; delete stakers[position].timestamps; } function retrieveNFT(uint256 tokenId) public{ (bool found,uint256 position) = isStakeholder(msg.sender); require(found, "You're not a stakeholder"); uint256 reward = calculateRewardIntern(position); _mint(msg.sender,reward); for(uint256 i = 0; i < stakers[position].tokenIds.length; i++){ if(stakers[position].tokenIds[i] == tokenId){ parent.safeTransferFrom(address(this), msg.sender, stakers[position].tokenIds[i], "0x00"); if(i != stakers[position].tokenIds.length - 1){ stakers[position].tokenIds[i] = stakers[position].tokenIds[stakers[position].tokenIds.length - 1]; stakers[position].timestamps[i] = stakers[position].timestamps[stakers[position].timestamps.length - 1]; } stakers[position].tokenIds.pop(); stakers[position].timestamps.pop(); break; } } } function retrieveNFTs(uint256 amount) public{ (bool found,uint256 position) = isStakeholder(msg.sender); require(found, "You're not a stakeholder"); require(stakers[position].tokenIds.length >= amount, "You're retrieving more than you staked."); uint256 reward = calculateRewardIntern(position); _mint(msg.sender,reward); for(uint256 i = 0; i < amount; i++){ parent.safeTransferFrom(address(this), msg.sender, stakers[position].tokenIds[i], "0x00"); if(i != stakers[position].tokenIds.length - 1){ stakers[position].tokenIds[i] = stakers[position].tokenIds[stakers[position].tokenIds.length - 1]; stakers[position].timestamps[i] = stakers[position].timestamps[stakers[position].timestamps.length - 1]; } stakers[position].tokenIds.pop(); stakers[position].timestamps.pop(); } } function checkOnRewardTime(uint256 tokenId) public view returns(string memory){ (bool found,uint256 position) = isStakeholder(msg.sender); require(found, "You're not a stakeholder"); for(uint256 i = 0; i < stakers[position].tokenIds.length; i++){ if(stakers[position].tokenIds[i] == tokenId){ if((block.timestamp - stakers[position].timestamps[i]) > timeOfReward) return "You can claim!"; uint256 calculated_time = timeOfReward - (block.timestamp - stakers[position].timestamps[i]); return string(abi.encodePacked(Strings.toString(calculated_time)," day/s")); } } return "This token is not staked"; } function checkOnRewardAmount(uint256 tokenId) public view returns(string memory){ (bool found,uint256 position) = isStakeholder(msg.sender); require(found, "You're not a stakeholder"); for(uint256 i = 0; i < stakers[position].tokenIds.length; i++){ if(stakers[position].tokenIds[i] == tokenId){ if((block.timestamp - stakers[position].timestamps[i]) < timeOfReward) return "Not claimable yet!"; uint256 calculated_reward = ((block.timestamp - stakers[position].timestamps[i]) / timeOfReward) * rewardPerDay; return string(abi.encodePacked(Strings.toString(calculated_reward),symbol())); } } return "This token is not staked"; } function changeRewardAmount(uint256 _newAmount) public onlyOwner{ rewardPerDay = _newAmount; } function changeTimeOfReward(uint256 _newTime) public onlyOwner{ timeOfReward = _newTime; } function nftOnStake() public view returns(uint256[] memory){ (bool found,uint256 position) = isStakeholder(msg.sender); require(found, "You're not a stakeholder"); return stakers[position].tokenIds; } }
/_openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
/_openzeppelin/contracts/token/ERC20/ERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens 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 amount ) 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, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
/_openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); }
/_openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
/_openzeppelin/contracts/token/ERC721/IERC721.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must 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 Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
/_openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
/_openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
/_openzeppelin/contracts/utils/Strings.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @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); } }
/_openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_NFTcontract","internalType":"address"},{"type":"uint256","name":"_rewardPerDay","internalType":"uint256"},{"type":"uint256","name":"_timeOfReward","internalType":"uint256"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeRewardAmount","inputs":[{"type":"uint256","name":"_newAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeTimeOfReward","inputs":[{"type":"uint256","name":"_newTime","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"checkOnRewardAmount","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"checkOnRewardTime","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claim","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"isStakeholder","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"nftOnStake","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes4","name":"","internalType":"bytes4"}],"name":"onERC721Received","inputs":[{"type":"address","name":"operator","internalType":"address"},{"type":"address","name":"from","internalType":"address"},{"type":"uint256","name":"tokenId","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC721"}],"name":"parent","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"retrieveAll","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"retrieveNFT","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"retrieveNFTs","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stake","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unlockNFTs","inputs":[]}]
Contract Creation Code
0x608060405264e8d4a510006008553480156200001a57600080fd5b506040516200484938038062004849833981810160405281019062000040919062000513565b6040518060400160405280600481526020017f47414e47000000000000000000000000000000000000000000000000000000008152506040518060400160405280600281526020017f2447000000000000000000000000000000000000000000000000000000000000815250620000cc620000c06200016f60201b60201c565b6200017760201b60201c565b8160049080519060200190620000e4929190620003be565b508060059080519060200190620000fd929190620003be565b50505082600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000158336402540be4006200023b60201b60201c565b81600a819055508060098190555050505062000710565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620002ad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002a490620005d0565b60405180910390fd5b620002c160008383620003b460201b60201c565b8060036000828254620002d5919062000621565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546200032d919062000621565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200039491906200068f565b60405180910390a3620003b060008383620003b960201b60201c565b5050565b505050565b505050565b828054620003cc90620006db565b90600052602060002090601f016020900481019282620003f057600085556200043c565b82601f106200040b57805160ff19168380011785556200043c565b828001600101855582156200043c579182015b828111156200043b5782518255916020019190600101906200041e565b5b5090506200044b91906200044f565b5090565b5b808211156200046a57600081600090555060010162000450565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004a08262000473565b9050919050565b620004b28162000493565b8114620004be57600080fd5b50565b600081519050620004d281620004a7565b92915050565b6000819050919050565b620004ed81620004d8565b8114620004f957600080fd5b50565b6000815190506200050d81620004e2565b92915050565b6000806000606084860312156200052f576200052e6200046e565b5b60006200053f86828701620004c1565b93505060206200055286828701620004fc565b92505060406200056586828701620004fc565b9150509250925092565b600082825260208201905092915050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000620005b8601f836200056f565b9150620005c58262000580565b602082019050919050565b60006020820190508181036000830152620005eb81620005a9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200062e82620004d8565b91506200063b83620004d8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620006735762000672620005f2565b5b828201905092915050565b6200068981620004d8565b82525050565b6000602082019050620006a660008301846200067e565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620006f457607f821691505b6020821081036200070a5762000709620006ac565b5b50919050565b61412980620007206000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80638da5cb5b116100f9578063a864504311610097578063b93833c311610071578063b93833c3146104e3578063dd62ed3e146104ff578063ef037b901461052f578063f2fde38b14610560576101c4565b8063a864504314610467578063a9059cbb14610483578063b06c63d6146104b3576101c4565b806395d89b41116100d357806395d89b41146103f3578063972ceaf714610411578063a457c2d71461041b578063a694fc3a1461044b576101c4565b80638da5cb5b146103af57806390449350146103cd57806395607ced146103e9576101c4565b8063313ce5671161016657806360f96a8f1161014057806360f96a8f146103395780636b47101c1461035757806370a0823114610375578063715018a6146103a5576101c4565b8063313ce567146102e157806339509351146102ff5780634e71d92d1461032f576101c4565b80630a1d7c5f116101a25780630a1d7c5f14610247578063150b7a021461026357806318160ddd1461029357806323b872dd146102b1576101c4565b806306975242146101c957806306fdde03146101f9578063095ea7b314610217575b600080fd5b6101e360048036038101906101de9190612f08565b61057c565b6040516101f09190612fce565b60405180910390f35b6102016107da565b60405161020e9190612fce565b60405180910390f35b610231600480360381019061022c919061304e565b61086c565b60405161023e91906130a9565b60405180910390f35b610261600480360381019061025c9190612f08565b61088f565b005b61027d60048036038101906102789190613129565b610caa565b60405161028a91906131ec565b60405180910390f35b61029b610e93565b6040516102a89190613216565b60405180910390f35b6102cb60048036038101906102c69190613231565b610e9d565b6040516102d891906130a9565b60405180910390f35b6102e9610ecc565b6040516102f691906132a0565b60405180910390f35b6103196004803603810190610314919061304e565b610ed5565b60405161032691906130a9565b60405180910390f35b610337610f0c565b005b610341610f78565b60405161034e919061331a565b60405180910390f35b61035f610f9e565b60405161036c91906133f3565b60405180910390f35b61038f600480360381019061038a9190613415565b61106b565b60405161039c9190613216565b60405180910390f35b6103ad6110b4565b005b6103b761113c565b6040516103c49190613451565b60405180910390f35b6103e760048036038101906103e29190612f08565b611165565b005b6103f16111eb565b005b6103fb6113d2565b6040516104089190612fce565b60405180910390f35b610419611464565b005b6104356004803603810190610430919061304e565b6116c6565b60405161044291906130a9565b60405180910390f35b61046560048036038101906104609190612f08565b61173d565b005b610481600480360381019061047c9190612f08565b61181c565b005b61049d6004803603810190610498919061304e565b611c2d565b6040516104aa91906130a9565b60405180910390f35b6104cd60048036038101906104c89190612f08565b611c50565b6040516104da9190612fce565b60405180910390f35b6104fd60048036038101906104f89190612f08565b611e98565b005b6105196004803603810190610514919061346c565b611f1e565b6040516105269190613216565b60405180910390f35b61054960048036038101906105449190613415565b611fa5565b6040516105579291906134ac565b60405180910390f35b61057a60048036038101906105759190613415565b61205e565b005b606060008061058a33611fa5565b91509150816105ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c590613521565b60405180910390fd5b60005b600782815481106105e5576105e4613541565b5b90600052602060002090600302016001018054905081101561079957846007838154811061061657610615613541565b5b9060005260206000209060030201600101828154811061063957610638613541565b5b90600052602060002001540361078657600954600783815481106106605761065f613541565b5b9060005260206000209060030201600201828154811061068357610682613541565b5b906000526020600020015442610699919061359f565b10156106df576040518060400160405280601281526020017f4e6f7420636c61696d61626c652079657421000000000000000000000000000081525093505050506107d5565b6000600a54600954600785815481106106fb576106fa613541565b5b9060005260206000209060030201600201848154811061071e5761071d613541565b5b906000526020600020015442610734919061359f565b61073e9190613602565b6107489190613633565b905061075381612155565b61075b6113d2565b60405160200161076c9291906136c9565b6040516020818303038152906040529450505050506107d5565b8080610791906136ed565b9150506105d1565b506040518060400160405280601881526020017f5468697320746f6b656e206973206e6f74207374616b65640000000000000000815250925050505b919050565b6060600480546107e990613764565b80601f016020809104026020016040519081016040528092919081815260200182805461081590613764565b80156108625780601f1061083757610100808354040283529160200191610862565b820191906000526020600020905b81548152906001019060200180831161084557829003601f168201915b5050505050905090565b6000806108776122b5565b90506108848185856122bd565b600191505092915050565b60008061089b33611fa5565b91509150816108df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d690613521565b60405180910390fd5b60006108ea82612486565b90506108f63382612644565b60005b6007838154811061090d5761090c613541565b5b906000526020600020906003020160010180549050811015610ca357846007848154811061093e5761093d613541565b5b9060005260206000209060030201600101828154811061096157610960613541565b5b906000526020600020015403610c9057600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde3033600787815481106109c5576109c4613541565b5b906000526020600020906003020160010185815481106109e8576109e7613541565b5b90600052602060002001546040518463ffffffff1660e01b8152600401610a11939291906137f2565b600060405180830381600087803b158015610a2b57600080fd5b505af1158015610a3f573d6000803e3d6000fd5b50505050600160078481548110610a5957610a58613541565b5b906000526020600020906003020160010180549050610a78919061359f565b8114610bf55760078381548110610a9257610a91613541565b5b9060005260206000209060030201600101600160078581548110610ab957610ab8613541565b5b906000526020600020906003020160010180549050610ad8919061359f565b81548110610ae957610ae8613541565b5b906000526020600020015460078481548110610b0857610b07613541565b5b90600052602060002090600302016001018281548110610b2b57610b2a613541565b5b906000526020600020018190555060078381548110610b4d57610b4c613541565b5b9060005260206000209060030201600201600160078581548110610b7457610b73613541565b5b906000526020600020906003020160020180549050610b93919061359f565b81548110610ba457610ba3613541565b5b906000526020600020015460078481548110610bc357610bc2613541565b5b90600052602060002090600302016002018281548110610be657610be5613541565b5b90600052602060002001819055505b60078381548110610c0957610c08613541565b5b9060005260206000209060030201600101805480610c2a57610c2961383c565b5b6001900381819060005260206000200160009055905560078381548110610c5457610c53613541565b5b9060005260206000209060030201600201805480610c7557610c7461383c565b5b60019003818190600052602060002001600090559055610ca3565b8080610c9b906136ed565b9150506108f9565b5050505050565b6000610cb685856127a4565b610e80576000600167ffffffffffffffff811115610cd757610cd661386b565b5b604051908082528060200260200182016040528015610d055781602001602082028036833780820191505090505b5090506000600167ffffffffffffffff811115610d2557610d2461386b565b5b604051908082528060200260200182016040528015610d535781602001602082028036833780820191505090505b5090508582600081518110610d6b57610d6a613541565b5b6020026020010181815250504281600081518110610d8c57610d8b613541565b5b602002602001018181525050600060405180606001604052808973ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838152509050600781908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001019080519060200190610e5c929190612e3d565b506040820151816002019080519060200190610e79929190612e3d565b5050505050505b63150b7a0260e01b905095945050505050565b6000600354905090565b600080610ea86122b5565b9050610eb5858285612860565b610ec08585856128ec565b60019150509392505050565b60006012905090565b600080610ee06122b5565b9050610f01818585610ef28589611f1e565b610efc919061389a565b6122bd565b600191505092915050565b600080610f1833611fa5565b9150915081610f5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5390613521565b60405180910390fd5b6000610f6782612b6e565b9050610f733382612644565b505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600080610fac33611fa5565b9150915081610ff0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe790613521565b60405180910390fd5b6007818154811061100457611003613541565b5b906000526020600020906003020160010180548060200260200160405190810160405280929190818152602001828054801561105f57602002820191906000526020600020905b81548152602001906001019080831161104b575b50505050509250505090565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6110bc6122b5565b73ffffffffffffffffffffffffffffffffffffffff166110da61113c565b73ffffffffffffffffffffffffffffffffffffffff1614611130576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111279061393c565b60405180910390fd5b61113a6000612d6f565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61116d6122b5565b73ffffffffffffffffffffffffffffffffffffffff1661118b61113c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d89061393c565b60405180910390fd5b8060098190555050565b6000806111f733611fa5565b915091508161123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123290613521565b60405180910390fd5b600061124682612486565b90506112523382612644565b60005b6007838154811061126957611268613541565b5b90600052602060002090600302016001018054905081101561136a57600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde3033600787815481106112d9576112d8613541565b5b906000526020600020906003020160010185815481106112fc576112fb613541565b5b90600052602060002001546040518463ffffffff1660e01b8152600401611325939291906137f2565b600060405180830381600087803b15801561133f57600080fd5b505af1158015611353573d6000803e3d6000fd5b505050508080611362906136ed565b915050611255565b506007828154811061137f5761137e613541565b5b9060005260206000209060030201600101600061139c9190612e8a565b600782815481106113b0576113af613541565b5b906000526020600020906003020160020160006113cd9190612e8a565b505050565b6060600580546113e190613764565b80601f016020809104026020016040519081016040528092919081815260200182805461140d90613764565b801561145a5780601f1061142f5761010080835404028352916020019161145a565b820191906000526020600020905b81548152906001019060200180831161143d57829003601f168201915b5050505050905090565b61146c6122b5565b73ffffffffffffffffffffffffffffffffffffffff1661148a61113c565b73ffffffffffffffffffffffffffffffffffffffff16146114e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d79061393c565b60405180910390fd5b60005b6007805490508110156116c35760005b6007828154811061150757611506613541565b5b90600052602060002090600302016001018054905081101561164d57600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde306007858154811061157657611575613541565b5b906000526020600020906003020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600786815481106115bc576115bb613541565b5b906000526020600020906003020160010185815481106115df576115de613541565b5b90600052602060002001546040518463ffffffff1660e01b8152600401611608939291906137f2565b600060405180830381600087803b15801561162257600080fd5b505af1158015611636573d6000803e3d6000fd5b505050508080611645906136ed565b9150506114f3565b506007818154811061166257611661613541565b5b9060005260206000209060030201600101600061167f9190612e8a565b6007818154811061169357611692613541565b5b906000526020600020906003020160020160006116b09190612e8a565b80806116bb906136ed565b9150506114e3565b50565b6000806116d16122b5565b905060006116df8286611f1e565b905083811015611724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171b906139ce565b60405180910390fd5b61173182868684036122bd565b60019250505092915050565b600854611748610e93565b10611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177f90613a60565b60405180910390fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde3330846040518463ffffffff1660e01b81526004016117e7939291906137f2565b600060405180830381600087803b15801561180157600080fd5b505af1158015611815573d6000803e3d6000fd5b5050505050565b60008061182833611fa5565b915091508161186c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186390613521565b60405180910390fd5b826007828154811061188157611880613541565b5b90600052602060002090600302016001018054905010156118d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ce90613af2565b60405180910390fd5b60006118e282612486565b90506118ee3382612644565b60005b84811015611c2657600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde30336007878154811061194d5761194c613541565b5b906000526020600020906003020160010185815481106119705761196f613541565b5b90600052602060002001546040518463ffffffff1660e01b8152600401611999939291906137f2565b600060405180830381600087803b1580156119b357600080fd5b505af11580156119c7573d6000803e3d6000fd5b505050506001600784815481106119e1576119e0613541565b5b906000526020600020906003020160010180549050611a00919061359f565b8114611b7d5760078381548110611a1a57611a19613541565b5b9060005260206000209060030201600101600160078581548110611a4157611a40613541565b5b906000526020600020906003020160010180549050611a60919061359f565b81548110611a7157611a70613541565b5b906000526020600020015460078481548110611a9057611a8f613541565b5b90600052602060002090600302016001018281548110611ab357611ab2613541565b5b906000526020600020018190555060078381548110611ad557611ad4613541565b5b9060005260206000209060030201600201600160078581548110611afc57611afb613541565b5b906000526020600020906003020160020180549050611b1b919061359f565b81548110611b2c57611b2b613541565b5b906000526020600020015460078481548110611b4b57611b4a613541565b5b90600052602060002090600302016002018281548110611b6e57611b6d613541565b5b90600052602060002001819055505b60078381548110611b9157611b90613541565b5b9060005260206000209060030201600101805480611bb257611bb161383c565b5b6001900381819060005260206000200160009055905560078381548110611bdc57611bdb613541565b5b9060005260206000209060030201600201805480611bfd57611bfc61383c565b5b600190038181906000526020600020016000905590558080611c1e906136ed565b9150506118f1565b5050505050565b600080611c386122b5565b9050611c458185856128ec565b600191505092915050565b6060600080611c5e33611fa5565b9150915081611ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9990613521565b60405180910390fd5b60005b60078281548110611cb957611cb8613541565b5b906000526020600020906003020160010180549050811015611e57578460078381548110611cea57611ce9613541565b5b90600052602060002090600302016001018281548110611d0d57611d0c613541565b5b906000526020600020015403611e445760095460078381548110611d3457611d33613541565b5b90600052602060002090600302016002018281548110611d5757611d56613541565b5b906000526020600020015442611d6d919061359f565b1115611db3576040518060400160405280600e81526020017f596f752063616e20636c61696d210000000000000000000000000000000000008152509350505050611e93565b600060078381548110611dc957611dc8613541565b5b90600052602060002090600302016002018281548110611dec57611deb613541565b5b906000526020600020015442611e02919061359f565b600954611e0f919061359f565b9050611e1a81612155565b604051602001611e2a9190613b5e565b604051602081830303815290604052945050505050611e93565b8080611e4f906136ed565b915050611ca5565b506040518060400160405280601881526020017f5468697320746f6b656e206973206e6f74207374616b65640000000000000000815250925050505b919050565b611ea06122b5565b73ffffffffffffffffffffffffffffffffffffffff16611ebe61113c565b73ffffffffffffffffffffffffffffffffffffffff1614611f14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0b9061393c565b60405180910390fd5b80600a8190555050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60008060005b600780549050811015612050578373ffffffffffffffffffffffffffffffffffffffff1660078281548110611fe357611fe2613541565b5b906000526020600020906003020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361203d576001819250925050612059565b8080612048906136ed565b915050611fab565b50600080915091505b915091565b6120666122b5565b73ffffffffffffffffffffffffffffffffffffffff1661208461113c565b73ffffffffffffffffffffffffffffffffffffffff16146120da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120d19061393c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214090613bf2565b60405180910390fd5b61215281612d6f565b50565b60606000820361219c576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506122b0565b600082905060005b600082146121ce5780806121b7906136ed565b915050600a826121c79190613602565b91506121a4565b60008167ffffffffffffffff8111156121ea576121e961386b565b5b6040519080825280601f01601f19166020018201604052801561221c5781602001600182028036833780820191505090505b5090505b600085146122a957600182612235919061359f565b9150600a856122449190613c12565b6030612250919061389a565b60f81b81838151811061226657612265613541565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856122a29190613602565b9450612220565b8093505050505b919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361232c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232390613cb5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361239b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239290613d47565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516124799190613216565b60405180910390a3505050565b6000806000905060005b600784815481106124a4576124a3613541565b5b9060005260206000209060030201600101805490508110156125ef576001600954600786815481106124d9576124d8613541565b5b906000526020600020906003020160020183815481106124fc576124fb613541565b5b906000526020600020015442612512919061359f565b61251c9190613602565b106125dc57600a546009546007868154811061253b5761253a613541565b5b9060005260206000209060030201600201838154811061255e5761255d613541565b5b906000526020600020015442612574919061359f565b61257e9190613602565b6125889190613633565b82612593919061389a565b915042600785815481106125aa576125a9613541565b5b906000526020600020906003020160020182815481106125cd576125cc613541565b5b90600052602060002001819055505b80806125e7906136ed565b915050612490565b506008546125fb610e93565b1061263b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161263290613db3565b60405180910390fd5b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126aa90613e1f565b60405180910390fd5b6126bf60008383612e33565b80600360008282546126d1919061389a565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612727919061389a565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161278c9190613216565b60405180910390a36127a060008383612e38565b5050565b60008060006127b285611fa5565b91509150811561285557600781815481106127d0576127cf613541565b5b90600052602060002090600302016001018490806001815401808255809150506001900390600052602060002001600090919091909150556007818154811061281c5761281b613541565b5b90600052602060002090600302016002014290806001815401808255809150506001900390600052602060002001600090919091909150555b819250505092915050565b600061286c8484611f1e565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146128e657818110156128d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128cf90613e8b565b60405180910390fd5b6128e584848484036122bd565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361295b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295290613f1d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129c190613faf565b60405180910390fd5b6129d5838383612e33565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612a5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a5390614041565b60405180910390fd5b818103600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612af1919061389a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b559190613216565b60405180910390a3612b68848484612e38565b50505050565b6000806000905060005b60078481548110612b8c57612b8b613541565b5b906000526020600020906003020160010180549050811015612cd757600160095460078681548110612bc157612bc0613541565b5b90600052602060002090600302016002018381548110612be457612be3613541565b5b906000526020600020015442612bfa919061359f565b612c049190613602565b10612cc457600a5460095460078681548110612c2357612c22613541565b5b90600052602060002090600302016002018381548110612c4657612c45613541565b5b906000526020600020015442612c5c919061359f565b612c669190613602565b612c709190613633565b82612c7b919061389a565b91504260078581548110612c9257612c91613541565b5b90600052602060002090600302016002018281548110612cb557612cb4613541565b5b90600052602060002001819055505b8080612ccf906136ed565b915050612b78565b5060008111612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d12906140d3565b60405180910390fd5b600854612d26610e93565b10612d66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d5d90613db3565b60405180910390fd5b80915050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b505050565b505050565b828054828255906000526020600020908101928215612e79579160200282015b82811115612e78578251825591602001919060010190612e5d565b5b509050612e869190612eab565b5090565b5080546000825590600052602060002090810190612ea89190612eab565b50565b5b80821115612ec4576000816000905550600101612eac565b5090565b600080fd5b600080fd5b6000819050919050565b612ee581612ed2565b8114612ef057600080fd5b50565b600081359050612f0281612edc565b92915050565b600060208284031215612f1e57612f1d612ec8565b5b6000612f2c84828501612ef3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612f6f578082015181840152602081019050612f54565b83811115612f7e576000848401525b50505050565b6000601f19601f8301169050919050565b6000612fa082612f35565b612faa8185612f40565b9350612fba818560208601612f51565b612fc381612f84565b840191505092915050565b60006020820190508181036000830152612fe88184612f95565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061301b82612ff0565b9050919050565b61302b81613010565b811461303657600080fd5b50565b60008135905061304881613022565b92915050565b6000806040838503121561306557613064612ec8565b5b600061307385828601613039565b925050602061308485828601612ef3565b9150509250929050565b60008115159050919050565b6130a38161308e565b82525050565b60006020820190506130be600083018461309a565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126130e9576130e86130c4565b5b8235905067ffffffffffffffff811115613106576131056130c9565b5b602083019150836001820283011115613122576131216130ce565b5b9250929050565b60008060008060006080868803121561314557613144612ec8565b5b600061315388828901613039565b955050602061316488828901613039565b945050604061317588828901612ef3565b935050606086013567ffffffffffffffff81111561319657613195612ecd565b5b6131a2888289016130d3565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6131e6816131b1565b82525050565b600060208201905061320160008301846131dd565b92915050565b61321081612ed2565b82525050565b600060208201905061322b6000830184613207565b92915050565b60008060006060848603121561324a57613249612ec8565b5b600061325886828701613039565b935050602061326986828701613039565b925050604061327a86828701612ef3565b9150509250925092565b600060ff82169050919050565b61329a81613284565b82525050565b60006020820190506132b56000830184613291565b92915050565b6000819050919050565b60006132e06132db6132d684612ff0565b6132bb565b612ff0565b9050919050565b60006132f2826132c5565b9050919050565b6000613304826132e7565b9050919050565b613314816132f9565b82525050565b600060208201905061332f600083018461330b565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61336a81612ed2565b82525050565b600061337c8383613361565b60208301905092915050565b6000602082019050919050565b60006133a082613335565b6133aa8185613340565b93506133b583613351565b8060005b838110156133e65781516133cd8882613370565b97506133d883613388565b9250506001810190506133b9565b5085935050505092915050565b6000602082019050818103600083015261340d8184613395565b905092915050565b60006020828403121561342b5761342a612ec8565b5b600061343984828501613039565b91505092915050565b61344b81613010565b82525050565b60006020820190506134666000830184613442565b92915050565b6000806040838503121561348357613482612ec8565b5b600061349185828601613039565b92505060206134a285828601613039565b9150509250929050565b60006040820190506134c1600083018561309a565b6134ce6020830184613207565b9392505050565b7f596f75277265206e6f742061207374616b65686f6c6465720000000000000000600082015250565b600061350b601883612f40565b9150613516826134d5565b602082019050919050565b6000602082019050818103600083015261353a816134fe565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006135aa82612ed2565b91506135b583612ed2565b9250828210156135c8576135c7613570565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061360d82612ed2565b915061361883612ed2565b925082613628576136276135d3565b5b828204905092915050565b600061363e82612ed2565b915061364983612ed2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561368257613681613570565b5b828202905092915050565b600081905092915050565b60006136a382612f35565b6136ad818561368d565b93506136bd818560208601612f51565b80840191505092915050565b60006136d58285613698565b91506136e18284613698565b91508190509392505050565b60006136f882612ed2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361372a57613729613570565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061377c57607f821691505b60208210810361378f5761378e613735565b5b50919050565b600082825260208201905092915050565b7f3078303000000000000000000000000000000000000000000000000000000000600082015250565b60006137dc600483613795565b91506137e7826137a6565b602082019050919050565b60006080820190506138076000830186613442565b6138146020830185613442565b6138216040830184613207565b8181036060830152613832816137cf565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006138a582612ed2565b91506138b083612ed2565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156138e5576138e4613570565b5b828201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613926602083612f40565b9150613931826138f0565b602082019050919050565b6000602082019050818103600083015261395581613919565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b60006139b8602583612f40565b91506139c38261395c565b604082019050919050565b600060208201905081810360008301526139e7816139ab565b9050919050565b7f49742773206e6f7420706f737369626c6520746f207374616b6520616e796d6f60008201527f7265000000000000000000000000000000000000000000000000000000000000602082015250565b6000613a4a602283612f40565b9150613a55826139ee565b604082019050919050565b60006020820190508181036000830152613a7981613a3d565b9050919050565b7f596f752772652072657472696576696e67206d6f7265207468616e20796f752060008201527f7374616b65642e00000000000000000000000000000000000000000000000000602082015250565b6000613adc602783612f40565b9150613ae782613a80565b604082019050919050565b60006020820190508181036000830152613b0b81613acf565b9050919050565b7f206461792f730000000000000000000000000000000000000000000000000000600082015250565b6000613b4860068361368d565b9150613b5382613b12565b600682019050919050565b6000613b6a8284613698565b9150613b7582613b3b565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613bdc602683612f40565b9150613be782613b80565b604082019050919050565b60006020820190508181036000830152613c0b81613bcf565b9050919050565b6000613c1d82612ed2565b9150613c2883612ed2565b925082613c3857613c376135d3565b5b828206905092915050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000613c9f602483612f40565b9150613caa82613c43565b604082019050919050565b60006020820190508181036000830152613cce81613c92565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d31602283612f40565b9150613d3c82613cd5565b604082019050919050565b60006020820190508181036000830152613d6081613d24565b9050919050565b7f596f752063616e2774206561726e20746f6b656e7320616e796d6f7265000000600082015250565b6000613d9d601d83612f40565b9150613da882613d67565b602082019050919050565b60006020820190508181036000830152613dcc81613d90565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000613e09601f83612f40565b9150613e1482613dd3565b602082019050919050565b60006020820190508181036000830152613e3881613dfc565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000613e75601d83612f40565b9150613e8082613e3f565b602082019050919050565b60006020820190508181036000830152613ea481613e68565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000613f07602583612f40565b9150613f1282613eab565b604082019050919050565b60006020820190508181036000830152613f3681613efa565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b6000613f99602383612f40565b9150613fa482613f3d565b604082019050919050565b60006020820190508181036000830152613fc881613f8c565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061402b602683612f40565b915061403682613fcf565b604082019050919050565b6000602082019050818103600083015261405a8161401e565b9050919050565b7f596f752063616e207769746864726177206f6e6c79206166746572203120646160008201527f7900000000000000000000000000000000000000000000000000000000000000602082015250565b60006140bd602183612f40565b91506140c882614061565b604082019050919050565b600060208201905081810360008301526140ec816140b0565b905091905056fea26469706673582212209c69d7d300916144fbbf35321a33c1c691e0e8a191a8dd21e150b4581631798664736f6c634300080e00330000000000000000000000003a337275cb5c4ff43d1c32e692c2ffb19012f6b200000000000000000000000000000000000000000000000000000000000007080000000000000000000000000000000000000000000000000000000000001900
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80638da5cb5b116100f9578063a864504311610097578063b93833c311610071578063b93833c3146104e3578063dd62ed3e146104ff578063ef037b901461052f578063f2fde38b14610560576101c4565b8063a864504314610467578063a9059cbb14610483578063b06c63d6146104b3576101c4565b806395d89b41116100d357806395d89b41146103f3578063972ceaf714610411578063a457c2d71461041b578063a694fc3a1461044b576101c4565b80638da5cb5b146103af57806390449350146103cd57806395607ced146103e9576101c4565b8063313ce5671161016657806360f96a8f1161014057806360f96a8f146103395780636b47101c1461035757806370a0823114610375578063715018a6146103a5576101c4565b8063313ce567146102e157806339509351146102ff5780634e71d92d1461032f576101c4565b80630a1d7c5f116101a25780630a1d7c5f14610247578063150b7a021461026357806318160ddd1461029357806323b872dd146102b1576101c4565b806306975242146101c957806306fdde03146101f9578063095ea7b314610217575b600080fd5b6101e360048036038101906101de9190612f08565b61057c565b6040516101f09190612fce565b60405180910390f35b6102016107da565b60405161020e9190612fce565b60405180910390f35b610231600480360381019061022c919061304e565b61086c565b60405161023e91906130a9565b60405180910390f35b610261600480360381019061025c9190612f08565b61088f565b005b61027d60048036038101906102789190613129565b610caa565b60405161028a91906131ec565b60405180910390f35b61029b610e93565b6040516102a89190613216565b60405180910390f35b6102cb60048036038101906102c69190613231565b610e9d565b6040516102d891906130a9565b60405180910390f35b6102e9610ecc565b6040516102f691906132a0565b60405180910390f35b6103196004803603810190610314919061304e565b610ed5565b60405161032691906130a9565b60405180910390f35b610337610f0c565b005b610341610f78565b60405161034e919061331a565b60405180910390f35b61035f610f9e565b60405161036c91906133f3565b60405180910390f35b61038f600480360381019061038a9190613415565b61106b565b60405161039c9190613216565b60405180910390f35b6103ad6110b4565b005b6103b761113c565b6040516103c49190613451565b60405180910390f35b6103e760048036038101906103e29190612f08565b611165565b005b6103f16111eb565b005b6103fb6113d2565b6040516104089190612fce565b60405180910390f35b610419611464565b005b6104356004803603810190610430919061304e565b6116c6565b60405161044291906130a9565b60405180910390f35b61046560048036038101906104609190612f08565b61173d565b005b610481600480360381019061047c9190612f08565b61181c565b005b61049d6004803603810190610498919061304e565b611c2d565b6040516104aa91906130a9565b60405180910390f35b6104cd60048036038101906104c89190612f08565b611c50565b6040516104da9190612fce565b60405180910390f35b6104fd60048036038101906104f89190612f08565b611e98565b005b6105196004803603810190610514919061346c565b611f1e565b6040516105269190613216565b60405180910390f35b61054960048036038101906105449190613415565b611fa5565b6040516105579291906134ac565b60405180910390f35b61057a60048036038101906105759190613415565b61205e565b005b606060008061058a33611fa5565b91509150816105ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c590613521565b60405180910390fd5b60005b600782815481106105e5576105e4613541565b5b90600052602060002090600302016001018054905081101561079957846007838154811061061657610615613541565b5b9060005260206000209060030201600101828154811061063957610638613541565b5b90600052602060002001540361078657600954600783815481106106605761065f613541565b5b9060005260206000209060030201600201828154811061068357610682613541565b5b906000526020600020015442610699919061359f565b10156106df576040518060400160405280601281526020017f4e6f7420636c61696d61626c652079657421000000000000000000000000000081525093505050506107d5565b6000600a54600954600785815481106106fb576106fa613541565b5b9060005260206000209060030201600201848154811061071e5761071d613541565b5b906000526020600020015442610734919061359f565b61073e9190613602565b6107489190613633565b905061075381612155565b61075b6113d2565b60405160200161076c9291906136c9565b6040516020818303038152906040529450505050506107d5565b8080610791906136ed565b9150506105d1565b506040518060400160405280601881526020017f5468697320746f6b656e206973206e6f74207374616b65640000000000000000815250925050505b919050565b6060600480546107e990613764565b80601f016020809104026020016040519081016040528092919081815260200182805461081590613764565b80156108625780601f1061083757610100808354040283529160200191610862565b820191906000526020600020905b81548152906001019060200180831161084557829003601f168201915b5050505050905090565b6000806108776122b5565b90506108848185856122bd565b600191505092915050565b60008061089b33611fa5565b91509150816108df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d690613521565b60405180910390fd5b60006108ea82612486565b90506108f63382612644565b60005b6007838154811061090d5761090c613541565b5b906000526020600020906003020160010180549050811015610ca357846007848154811061093e5761093d613541565b5b9060005260206000209060030201600101828154811061096157610960613541565b5b906000526020600020015403610c9057600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde3033600787815481106109c5576109c4613541565b5b906000526020600020906003020160010185815481106109e8576109e7613541565b5b90600052602060002001546040518463ffffffff1660e01b8152600401610a11939291906137f2565b600060405180830381600087803b158015610a2b57600080fd5b505af1158015610a3f573d6000803e3d6000fd5b50505050600160078481548110610a5957610a58613541565b5b906000526020600020906003020160010180549050610a78919061359f565b8114610bf55760078381548110610a9257610a91613541565b5b9060005260206000209060030201600101600160078581548110610ab957610ab8613541565b5b906000526020600020906003020160010180549050610ad8919061359f565b81548110610ae957610ae8613541565b5b906000526020600020015460078481548110610b0857610b07613541565b5b90600052602060002090600302016001018281548110610b2b57610b2a613541565b5b906000526020600020018190555060078381548110610b4d57610b4c613541565b5b9060005260206000209060030201600201600160078581548110610b7457610b73613541565b5b906000526020600020906003020160020180549050610b93919061359f565b81548110610ba457610ba3613541565b5b906000526020600020015460078481548110610bc357610bc2613541565b5b90600052602060002090600302016002018281548110610be657610be5613541565b5b90600052602060002001819055505b60078381548110610c0957610c08613541565b5b9060005260206000209060030201600101805480610c2a57610c2961383c565b5b6001900381819060005260206000200160009055905560078381548110610c5457610c53613541565b5b9060005260206000209060030201600201805480610c7557610c7461383c565b5b60019003818190600052602060002001600090559055610ca3565b8080610c9b906136ed565b9150506108f9565b5050505050565b6000610cb685856127a4565b610e80576000600167ffffffffffffffff811115610cd757610cd661386b565b5b604051908082528060200260200182016040528015610d055781602001602082028036833780820191505090505b5090506000600167ffffffffffffffff811115610d2557610d2461386b565b5b604051908082528060200260200182016040528015610d535781602001602082028036833780820191505090505b5090508582600081518110610d6b57610d6a613541565b5b6020026020010181815250504281600081518110610d8c57610d8b613541565b5b602002602001018181525050600060405180606001604052808973ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838152509050600781908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001019080519060200190610e5c929190612e3d565b506040820151816002019080519060200190610e79929190612e3d565b5050505050505b63150b7a0260e01b905095945050505050565b6000600354905090565b600080610ea86122b5565b9050610eb5858285612860565b610ec08585856128ec565b60019150509392505050565b60006012905090565b600080610ee06122b5565b9050610f01818585610ef28589611f1e565b610efc919061389a565b6122bd565b600191505092915050565b600080610f1833611fa5565b9150915081610f5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5390613521565b60405180910390fd5b6000610f6782612b6e565b9050610f733382612644565b505050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600080610fac33611fa5565b9150915081610ff0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe790613521565b60405180910390fd5b6007818154811061100457611003613541565b5b906000526020600020906003020160010180548060200260200160405190810160405280929190818152602001828054801561105f57602002820191906000526020600020905b81548152602001906001019080831161104b575b50505050509250505090565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6110bc6122b5565b73ffffffffffffffffffffffffffffffffffffffff166110da61113c565b73ffffffffffffffffffffffffffffffffffffffff1614611130576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111279061393c565b60405180910390fd5b61113a6000612d6f565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61116d6122b5565b73ffffffffffffffffffffffffffffffffffffffff1661118b61113c565b73ffffffffffffffffffffffffffffffffffffffff16146111e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d89061393c565b60405180910390fd5b8060098190555050565b6000806111f733611fa5565b915091508161123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123290613521565b60405180910390fd5b600061124682612486565b90506112523382612644565b60005b6007838154811061126957611268613541565b5b90600052602060002090600302016001018054905081101561136a57600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde3033600787815481106112d9576112d8613541565b5b906000526020600020906003020160010185815481106112fc576112fb613541565b5b90600052602060002001546040518463ffffffff1660e01b8152600401611325939291906137f2565b600060405180830381600087803b15801561133f57600080fd5b505af1158015611353573d6000803e3d6000fd5b505050508080611362906136ed565b915050611255565b506007828154811061137f5761137e613541565b5b9060005260206000209060030201600101600061139c9190612e8a565b600782815481106113b0576113af613541565b5b906000526020600020906003020160020160006113cd9190612e8a565b505050565b6060600580546113e190613764565b80601f016020809104026020016040519081016040528092919081815260200182805461140d90613764565b801561145a5780601f1061142f5761010080835404028352916020019161145a565b820191906000526020600020905b81548152906001019060200180831161143d57829003601f168201915b5050505050905090565b61146c6122b5565b73ffffffffffffffffffffffffffffffffffffffff1661148a61113c565b73ffffffffffffffffffffffffffffffffffffffff16146114e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d79061393c565b60405180910390fd5b60005b6007805490508110156116c35760005b6007828154811061150757611506613541565b5b90600052602060002090600302016001018054905081101561164d57600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde306007858154811061157657611575613541565b5b906000526020600020906003020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600786815481106115bc576115bb613541565b5b906000526020600020906003020160010185815481106115df576115de613541565b5b90600052602060002001546040518463ffffffff1660e01b8152600401611608939291906137f2565b600060405180830381600087803b15801561162257600080fd5b505af1158015611636573d6000803e3d6000fd5b505050508080611645906136ed565b9150506114f3565b506007818154811061166257611661613541565b5b9060005260206000209060030201600101600061167f9190612e8a565b6007818154811061169357611692613541565b5b906000526020600020906003020160020160006116b09190612e8a565b80806116bb906136ed565b9150506114e3565b50565b6000806116d16122b5565b905060006116df8286611f1e565b905083811015611724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171b906139ce565b60405180910390fd5b61173182868684036122bd565b60019250505092915050565b600854611748610e93565b10611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177f90613a60565b60405180910390fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde3330846040518463ffffffff1660e01b81526004016117e7939291906137f2565b600060405180830381600087803b15801561180157600080fd5b505af1158015611815573d6000803e3d6000fd5b5050505050565b60008061182833611fa5565b915091508161186c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186390613521565b60405180910390fd5b826007828154811061188157611880613541565b5b90600052602060002090600302016001018054905010156118d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ce90613af2565b60405180910390fd5b60006118e282612486565b90506118ee3382612644565b60005b84811015611c2657600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b88d4fde30336007878154811061194d5761194c613541565b5b906000526020600020906003020160010185815481106119705761196f613541565b5b90600052602060002001546040518463ffffffff1660e01b8152600401611999939291906137f2565b600060405180830381600087803b1580156119b357600080fd5b505af11580156119c7573d6000803e3d6000fd5b505050506001600784815481106119e1576119e0613541565b5b906000526020600020906003020160010180549050611a00919061359f565b8114611b7d5760078381548110611a1a57611a19613541565b5b9060005260206000209060030201600101600160078581548110611a4157611a40613541565b5b906000526020600020906003020160010180549050611a60919061359f565b81548110611a7157611a70613541565b5b906000526020600020015460078481548110611a9057611a8f613541565b5b90600052602060002090600302016001018281548110611ab357611ab2613541565b5b906000526020600020018190555060078381548110611ad557611ad4613541565b5b9060005260206000209060030201600201600160078581548110611afc57611afb613541565b5b906000526020600020906003020160020180549050611b1b919061359f565b81548110611b2c57611b2b613541565b5b906000526020600020015460078481548110611b4b57611b4a613541565b5b90600052602060002090600302016002018281548110611b6e57611b6d613541565b5b90600052602060002001819055505b60078381548110611b9157611b90613541565b5b9060005260206000209060030201600101805480611bb257611bb161383c565b5b6001900381819060005260206000200160009055905560078381548110611bdc57611bdb613541565b5b9060005260206000209060030201600201805480611bfd57611bfc61383c565b5b600190038181906000526020600020016000905590558080611c1e906136ed565b9150506118f1565b5050505050565b600080611c386122b5565b9050611c458185856128ec565b600191505092915050565b6060600080611c5e33611fa5565b9150915081611ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9990613521565b60405180910390fd5b60005b60078281548110611cb957611cb8613541565b5b906000526020600020906003020160010180549050811015611e57578460078381548110611cea57611ce9613541565b5b90600052602060002090600302016001018281548110611d0d57611d0c613541565b5b906000526020600020015403611e445760095460078381548110611d3457611d33613541565b5b90600052602060002090600302016002018281548110611d5757611d56613541565b5b906000526020600020015442611d6d919061359f565b1115611db3576040518060400160405280600e81526020017f596f752063616e20636c61696d210000000000000000000000000000000000008152509350505050611e93565b600060078381548110611dc957611dc8613541565b5b90600052602060002090600302016002018281548110611dec57611deb613541565b5b906000526020600020015442611e02919061359f565b600954611e0f919061359f565b9050611e1a81612155565b604051602001611e2a9190613b5e565b604051602081830303815290604052945050505050611e93565b8080611e4f906136ed565b915050611ca5565b506040518060400160405280601881526020017f5468697320746f6b656e206973206e6f74207374616b65640000000000000000815250925050505b919050565b611ea06122b5565b73ffffffffffffffffffffffffffffffffffffffff16611ebe61113c565b73ffffffffffffffffffffffffffffffffffffffff1614611f14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0b9061393c565b60405180910390fd5b80600a8190555050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60008060005b600780549050811015612050578373ffffffffffffffffffffffffffffffffffffffff1660078281548110611fe357611fe2613541565b5b906000526020600020906003020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361203d576001819250925050612059565b8080612048906136ed565b915050611fab565b50600080915091505b915091565b6120666122b5565b73ffffffffffffffffffffffffffffffffffffffff1661208461113c565b73ffffffffffffffffffffffffffffffffffffffff16146120da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120d19061393c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214090613bf2565b60405180910390fd5b61215281612d6f565b50565b60606000820361219c576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506122b0565b600082905060005b600082146121ce5780806121b7906136ed565b915050600a826121c79190613602565b91506121a4565b60008167ffffffffffffffff8111156121ea576121e961386b565b5b6040519080825280601f01601f19166020018201604052801561221c5781602001600182028036833780820191505090505b5090505b600085146122a957600182612235919061359f565b9150600a856122449190613c12565b6030612250919061389a565b60f81b81838151811061226657612265613541565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856122a29190613602565b9450612220565b8093505050505b919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361232c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232390613cb5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361239b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239290613d47565b60405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516124799190613216565b60405180910390a3505050565b6000806000905060005b600784815481106124a4576124a3613541565b5b9060005260206000209060030201600101805490508110156125ef576001600954600786815481106124d9576124d8613541565b5b906000526020600020906003020160020183815481106124fc576124fb613541565b5b906000526020600020015442612512919061359f565b61251c9190613602565b106125dc57600a546009546007868154811061253b5761253a613541565b5b9060005260206000209060030201600201838154811061255e5761255d613541565b5b906000526020600020015442612574919061359f565b61257e9190613602565b6125889190613633565b82612593919061389a565b915042600785815481106125aa576125a9613541565b5b906000526020600020906003020160020182815481106125cd576125cc613541565b5b90600052602060002001819055505b80806125e7906136ed565b915050612490565b506008546125fb610e93565b1061263b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161263290613db3565b60405180910390fd5b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126aa90613e1f565b60405180910390fd5b6126bf60008383612e33565b80600360008282546126d1919061389a565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612727919061389a565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161278c9190613216565b60405180910390a36127a060008383612e38565b5050565b60008060006127b285611fa5565b91509150811561285557600781815481106127d0576127cf613541565b5b90600052602060002090600302016001018490806001815401808255809150506001900390600052602060002001600090919091909150556007818154811061281c5761281b613541565b5b90600052602060002090600302016002014290806001815401808255809150506001900390600052602060002001600090919091909150555b819250505092915050565b600061286c8484611f1e565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146128e657818110156128d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128cf90613e8b565b60405180910390fd5b6128e584848484036122bd565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361295b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295290613f1d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036129ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129c190613faf565b60405180910390fd5b6129d5838383612e33565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612a5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a5390614041565b60405180910390fd5b818103600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612af1919061389a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b559190613216565b60405180910390a3612b68848484612e38565b50505050565b6000806000905060005b60078481548110612b8c57612b8b613541565b5b906000526020600020906003020160010180549050811015612cd757600160095460078681548110612bc157612bc0613541565b5b90600052602060002090600302016002018381548110612be457612be3613541565b5b906000526020600020015442612bfa919061359f565b612c049190613602565b10612cc457600a5460095460078681548110612c2357612c22613541565b5b90600052602060002090600302016002018381548110612c4657612c45613541565b5b906000526020600020015442612c5c919061359f565b612c669190613602565b612c709190613633565b82612c7b919061389a565b91504260078581548110612c9257612c91613541565b5b90600052602060002090600302016002018281548110612cb557612cb4613541565b5b90600052602060002001819055505b8080612ccf906136ed565b915050612b78565b5060008111612d1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d12906140d3565b60405180910390fd5b600854612d26610e93565b10612d66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d5d90613db3565b60405180910390fd5b80915050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b505050565b505050565b828054828255906000526020600020908101928215612e79579160200282015b82811115612e78578251825591602001919060010190612e5d565b5b509050612e869190612eab565b5090565b5080546000825590600052602060002090810190612ea89190612eab565b50565b5b80821115612ec4576000816000905550600101612eac565b5090565b600080fd5b600080fd5b6000819050919050565b612ee581612ed2565b8114612ef057600080fd5b50565b600081359050612f0281612edc565b92915050565b600060208284031215612f1e57612f1d612ec8565b5b6000612f2c84828501612ef3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612f6f578082015181840152602081019050612f54565b83811115612f7e576000848401525b50505050565b6000601f19601f8301169050919050565b6000612fa082612f35565b612faa8185612f40565b9350612fba818560208601612f51565b612fc381612f84565b840191505092915050565b60006020820190508181036000830152612fe88184612f95565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061301b82612ff0565b9050919050565b61302b81613010565b811461303657600080fd5b50565b60008135905061304881613022565b92915050565b6000806040838503121561306557613064612ec8565b5b600061307385828601613039565b925050602061308485828601612ef3565b9150509250929050565b60008115159050919050565b6130a38161308e565b82525050565b60006020820190506130be600083018461309a565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126130e9576130e86130c4565b5b8235905067ffffffffffffffff811115613106576131056130c9565b5b602083019150836001820283011115613122576131216130ce565b5b9250929050565b60008060008060006080868803121561314557613144612ec8565b5b600061315388828901613039565b955050602061316488828901613039565b945050604061317588828901612ef3565b935050606086013567ffffffffffffffff81111561319657613195612ecd565b5b6131a2888289016130d3565b92509250509295509295909350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6131e6816131b1565b82525050565b600060208201905061320160008301846131dd565b92915050565b61321081612ed2565b82525050565b600060208201905061322b6000830184613207565b92915050565b60008060006060848603121561324a57613249612ec8565b5b600061325886828701613039565b935050602061326986828701613039565b925050604061327a86828701612ef3565b9150509250925092565b600060ff82169050919050565b61329a81613284565b82525050565b60006020820190506132b56000830184613291565b92915050565b6000819050919050565b60006132e06132db6132d684612ff0565b6132bb565b612ff0565b9050919050565b60006132f2826132c5565b9050919050565b6000613304826132e7565b9050919050565b613314816132f9565b82525050565b600060208201905061332f600083018461330b565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61336a81612ed2565b82525050565b600061337c8383613361565b60208301905092915050565b6000602082019050919050565b60006133a082613335565b6133aa8185613340565b93506133b583613351565b8060005b838110156133e65781516133cd8882613370565b97506133d883613388565b9250506001810190506133b9565b5085935050505092915050565b6000602082019050818103600083015261340d8184613395565b905092915050565b60006020828403121561342b5761342a612ec8565b5b600061343984828501613039565b91505092915050565b61344b81613010565b82525050565b60006020820190506134666000830184613442565b92915050565b6000806040838503121561348357613482612ec8565b5b600061349185828601613039565b92505060206134a285828601613039565b9150509250929050565b60006040820190506134c1600083018561309a565b6134ce6020830184613207565b9392505050565b7f596f75277265206e6f742061207374616b65686f6c6465720000000000000000600082015250565b600061350b601883612f40565b9150613516826134d5565b602082019050919050565b6000602082019050818103600083015261353a816134fe565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006135aa82612ed2565b91506135b583612ed2565b9250828210156135c8576135c7613570565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061360d82612ed2565b915061361883612ed2565b925082613628576136276135d3565b5b828204905092915050565b600061363e82612ed2565b915061364983612ed2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561368257613681613570565b5b828202905092915050565b600081905092915050565b60006136a382612f35565b6136ad818561368d565b93506136bd818560208601612f51565b80840191505092915050565b60006136d58285613698565b91506136e18284613698565b91508190509392505050565b60006136f882612ed2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361372a57613729613570565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061377c57607f821691505b60208210810361378f5761378e613735565b5b50919050565b600082825260208201905092915050565b7f3078303000000000000000000000000000000000000000000000000000000000600082015250565b60006137dc600483613795565b91506137e7826137a6565b602082019050919050565b60006080820190506138076000830186613442565b6138146020830185613442565b6138216040830184613207565b8181036060830152613832816137cf565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006138a582612ed2565b91506138b083612ed2565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156138e5576138e4613570565b5b828201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613926602083612f40565b9150613931826138f0565b602082019050919050565b6000602082019050818103600083015261395581613919565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b60006139b8602583612f40565b91506139c38261395c565b604082019050919050565b600060208201905081810360008301526139e7816139ab565b9050919050565b7f49742773206e6f7420706f737369626c6520746f207374616b6520616e796d6f60008201527f7265000000000000000000000000000000000000000000000000000000000000602082015250565b6000613a4a602283612f40565b9150613a55826139ee565b604082019050919050565b60006020820190508181036000830152613a7981613a3d565b9050919050565b7f596f752772652072657472696576696e67206d6f7265207468616e20796f752060008201527f7374616b65642e00000000000000000000000000000000000000000000000000602082015250565b6000613adc602783612f40565b9150613ae782613a80565b604082019050919050565b60006020820190508181036000830152613b0b81613acf565b9050919050565b7f206461792f730000000000000000000000000000000000000000000000000000600082015250565b6000613b4860068361368d565b9150613b5382613b12565b600682019050919050565b6000613b6a8284613698565b9150613b7582613b3b565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613bdc602683612f40565b9150613be782613b80565b604082019050919050565b60006020820190508181036000830152613c0b81613bcf565b9050919050565b6000613c1d82612ed2565b9150613c2883612ed2565b925082613c3857613c376135d3565b5b828206905092915050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000613c9f602483612f40565b9150613caa82613c43565b604082019050919050565b60006020820190508181036000830152613cce81613c92565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d31602283612f40565b9150613d3c82613cd5565b604082019050919050565b60006020820190508181036000830152613d6081613d24565b9050919050565b7f596f752063616e2774206561726e20746f6b656e7320616e796d6f7265000000600082015250565b6000613d9d601d83612f40565b9150613da882613d67565b602082019050919050565b60006020820190508181036000830152613dcc81613d90565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000613e09601f83612f40565b9150613e1482613dd3565b602082019050919050565b60006020820190508181036000830152613e3881613dfc565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000613e75601d83612f40565b9150613e8082613e3f565b602082019050919050565b60006020820190508181036000830152613ea481613e68565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000613f07602583612f40565b9150613f1282613eab565b604082019050919050565b60006020820190508181036000830152613f3681613efa565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b6000613f99602383612f40565b9150613fa482613f3d565b604082019050919050565b60006020820190508181036000830152613fc881613f8c565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061402b602683612f40565b915061403682613fcf565b604082019050919050565b6000602082019050818103600083015261405a8161401e565b9050919050565b7f596f752063616e207769746864726177206f6e6c79206166746572203120646160008201527f7900000000000000000000000000000000000000000000000000000000000000602082015250565b60006140bd602183612f40565b91506140c882614061565b604082019050919050565b600060208201905081810360008301526140ec816140b0565b905091905056fea26469706673582212209c69d7d300916144fbbf35321a33c1c691e0e8a191a8dd21e150b4581631798664736f6c634300080e0033