Address Details
contract
0x438d727b434b6126aF6a91AcBf7Ce9e2a1A967c8
- Contract Name
- CeloEduMarketplace
- Creator
- 0x92ed65–55ad42 at 0xff9b35–53d573
- 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
- 17 Transactions
- Transfers
- 0 Transfers
- Gas Used
- 2,027,794
- Last Balance Update
- 11536199
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- CeloEduMarketplace
- Optimization enabled
- false
- Compiler version
- v0.8.7+commit.e28d00a7
- EVM Version
- london
- Verified at
- 2022-05-20T03:13:52.008197Z
CeloEduMarketplace.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0 <0.9.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract CeloEduMarketplace { using Counters for Counters.Counter; address internal cUSDTokenAddress = 0x874069Fa1Eb16D44d622F2e0Ca25eeA172369bC1; struct Course { address payable owner; string title; string description; string author; string image; uint price; uint sold; } struct Learner { address owner; bool isComplete; } mapping(uint256 => Course) internal courses; mapping(uint256 => Learner[]) internal learners; Counters.Counter public totalCourses; function addCourse( string memory _title, string memory _description, string memory _author, string memory _image, uint _price ) public { uint256 courseIndex = totalCourses.current(); totalCourses.increment(); uint _sold = 0; courses[courseIndex] = Course( payable(msg.sender), _title, _description, _author, _image, _price, _sold ); } function getCourse(uint _index) public view returns ( address payable, string memory, string memory, string memory, string memory, uint, uint ) { Course storage c = courses[_index]; return ( c.owner, c.title, c.description, c.author, c.image, c.price, c.sold ); } function buyCourse(uint _index) public payable { IERC20 cUSD = IERC20(cUSDTokenAddress); Course storage c = courses[_index]; require(!isBoughtCourse(_index), "Course has already been bought"); require(cUSD.balanceOf(msg.sender) > c.price, "Not enough cUSD"); require( cUSD.transferFrom( msg.sender, c.owner, c.price ), "Failed to transfer funds" ); c.sold++; learners[_index].push(Learner(msg.sender, false)); } function completeCourse(uint _index) public payable { require(isBoughtCourse(_index), "Need to buy course first"); require(!isCompleteCourse(_index), "Course is already complete"); Learner[] storage _learners = learners[_index]; for (uint i = 0; i < _learners.length; i++) { if (_learners[i].owner == msg.sender) { _learners[i].isComplete = true; break; } } } function isBoughtCourse(uint _index) public view returns (bool) { Learner[] memory _learners = getCourseLearners(_index); for (uint i = 0; i < _learners.length; i++) { if (_learners[i].owner == msg.sender) { return true; } } return false; } function isCompleteCourse(uint _index) public view returns (bool) { Learner[] memory _learners = getCourseLearners(_index); for (uint i = 0; i < _learners.length; i++) { if (_learners[i].isComplete) { return true; } } return false; } function getCourseLearners(uint _index) public view returns (Learner[] memory) { Learner[] memory _learners = learners[_index]; return _learners; } }
/_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/utils/Counters.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
Contract ABI
[{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addCourse","inputs":[{"type":"string","name":"_title","internalType":"string"},{"type":"string","name":"_description","internalType":"string"},{"type":"string","name":"_author","internalType":"string"},{"type":"string","name":"_image","internalType":"string"},{"type":"uint256","name":"_price","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"buyCourse","inputs":[{"type":"uint256","name":"_index","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"completeCourse","inputs":[{"type":"uint256","name":"_index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"},{"type":"string","name":"","internalType":"string"},{"type":"string","name":"","internalType":"string"},{"type":"string","name":"","internalType":"string"},{"type":"string","name":"","internalType":"string"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCourse","inputs":[{"type":"uint256","name":"_index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct CeloEduMarketplace.Learner[]","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isComplete","internalType":"bool"}]}],"name":"getCourseLearners","inputs":[{"type":"uint256","name":"_index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isBoughtCourse","inputs":[{"type":"uint256","name":"_index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isCompleteCourse","inputs":[{"type":"uint256","name":"_index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_value","internalType":"uint256"}],"name":"totalCourses","inputs":[]}]
Contract Creation Code
0x608060405273874069fa1eb16d44d622f2e0ca25eea172369bc16000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561006457600080fd5b50611798806100746000396000f3fe60806040526004361061007b5760003560e01c806337f66bb71161004e57806337f66bb71461013857806372bc10021461017557806387ac18601461019e578063e3a62c32146101c95761007b565b80630b91e28d146100805780630d3b4292146100c357806315876d43146100df578063194d73a21461011c575b600080fd5b34801561008c57600080fd5b506100a760048036038101906100a29190610f38565b610206565b6040516100ba97969594939291906111a3565b60405180910390f35b6100dd60048036038101906100d89190610f38565b6104b1565b005b3480156100eb57600080fd5b5061010660048036038101906101019190610f38565b610632565b6040516101139190611287565b60405180910390f35b61013660048036038101906101319190610f38565b6106c8565b005b34801561014457600080fd5b5061015f600480360381019061015a9190610f38565b610a00565b60405161016c9190611287565b60405180910390f35b34801561018157600080fd5b5061019c60048036038101906101979190610e4d565b610a68565b005b3480156101aa57600080fd5b506101b3610bb9565b6040516101c09190611342565b60405180910390f35b3480156101d557600080fd5b506101f060048036038101906101eb9190610f38565b610bc5565b6040516101fd9190611265565b60405180910390f35b60006060806060806000806000600160008a815260200190815260200160002090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160010182600201836003018460040185600501548660060154858054610273906114da565b80601f016020809104026020016040519081016040528092919081815260200182805461029f906114da565b80156102ec5780601f106102c1576101008083540402835291602001916102ec565b820191906000526020600020905b8154815290600101906020018083116102cf57829003601f168201915b505050505095508480546102ff906114da565b80601f016020809104026020016040519081016040528092919081815260200182805461032b906114da565b80156103785780601f1061034d57610100808354040283529160200191610378565b820191906000526020600020905b81548152906001019060200180831161035b57829003601f168201915b5050505050945083805461038b906114da565b80601f01602080910402602001604051908101604052809291908181526020018280546103b7906114da565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b50505050509350828054610417906114da565b80601f0160208091040260200160405190810160405280929190818152602001828054610443906114da565b80156104905780601f1061046557610100808354040283529160200191610490565b820191906000526020600020905b81548152906001019060200180831161047357829003601f168201915b50505050509250975097509750975097509750975050919395979092949650565b6104ba81610632565b6104f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f090611302565b60405180910390fd5b61050281610a00565b15610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990611322565b60405180910390fd5b600060026000838152602001908152602001600020905060005b818054905081101561062d573373ffffffffffffffffffffffffffffffffffffffff16828281548110610592576105916115e4565b5b9060005260206000200160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561061a5760018282815481106105f1576105f06115e4565b5b9060005260206000200160000160146101000a81548160ff02191690831515021790555061062d565b80806106259061153d565b91505061055c565b505050565b60008061063e83610bc5565b905060005b81518110156106bc573373ffffffffffffffffffffffffffffffffffffffff16828281518110610676576106756115e4565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1614156106a9576001925050506106c3565b80806106b49061153d565b915050610643565b5060009150505b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600060016000848152602001908152602001600020905061070e83610632565b1561074e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610745906112c2565b60405180910390fd5b80600501548273ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b815260040161078c9190611188565b60206040518083038186803b1580156107a457600080fd5b505afa1580156107b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dc9190610f65565b1161081c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610813906112e2565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd338360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684600501546040518463ffffffff1660e01b81526004016108819392919061122e565b602060405180830381600087803b15801561089b57600080fd5b505af11580156108af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d39190610e20565b610912576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610909906112a2565b60405180910390fd5b8060060160008154809291906109279061153d565b91905055506002600084815260200190815260200160002060405180604001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff0219169083151502179055505050505050565b600080610a0c83610bc5565b905060005b8151811015610a5c57818181518110610a2d57610a2c6115e4565b5b60200260200101516020015115610a4957600192505050610a63565b8080610a549061153d565b915050610a11565b5060009150505b919050565b6000610a746003610caa565b9050610a806003610cb8565b60006040518060e001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001888152602001878152602001868152602001858152602001848152602001828152506001600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001019080519060200190610b41929190610cce565b506040820151816002019080519060200190610b5e929190610cce565b506060820151816003019080519060200190610b7b929190610cce565b506080820151816004019080519060200190610b98929190610cce565b5060a0820151816005015560c0820151816006015590505050505050505050565b60038060000154905081565b6060600060026000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610c9b578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff16151515158152505081526020019060010190610bfc565b50505050905080915050919050565b600081600001549050919050565b6001816000016000828254019250508190555050565b828054610cda906114da565b90600052602060002090601f016020900481019282610cfc5760008555610d43565b82601f10610d1557805160ff1916838001178555610d43565b82800160010185558215610d43579182015b82811115610d42578251825591602001919060010190610d27565b5b509050610d509190610d54565b5090565b5b80821115610d6d576000816000905550600101610d55565b5090565b6000610d84610d7f84611382565b61135d565b905082815260208101848484011115610da057610d9f611647565b5b610dab848285611498565b509392505050565b600081519050610dc281611734565b92915050565b600082601f830112610ddd57610ddc611642565b5b8135610ded848260208601610d71565b91505092915050565b600081359050610e058161174b565b92915050565b600081519050610e1a8161174b565b92915050565b600060208284031215610e3657610e35611651565b5b6000610e4484828501610db3565b91505092915050565b600080600080600060a08688031215610e6957610e68611651565b5b600086013567ffffffffffffffff811115610e8757610e8661164c565b5b610e9388828901610dc8565b955050602086013567ffffffffffffffff811115610eb457610eb361164c565b5b610ec088828901610dc8565b945050604086013567ffffffffffffffff811115610ee157610ee061164c565b5b610eed88828901610dc8565b935050606086013567ffffffffffffffff811115610f0e57610f0d61164c565b5b610f1a88828901610dc8565b9250506080610f2b88828901610df6565b9150509295509295909350565b600060208284031215610f4e57610f4d611651565b5b6000610f5c84828501610df6565b91505092915050565b600060208284031215610f7b57610f7a611651565b5b6000610f8984828501610e0b565b91505092915050565b6000610f9e838361114a565b60408301905092915050565b610fb381611462565b82525050565b610fc28161141a565b82525050565b610fd181611408565b82525050565b610fe081611408565b82525050565b6000610ff1826113c3565b610ffb81856113e6565b9350611006836113b3565b8060005b8381101561103757815161101e8882610f92565b9750611029836113d9565b92505060018101905061100a565b5085935050505092915050565b61104d8161142c565b82525050565b61105c8161142c565b82525050565b600061106d826113ce565b61107781856113f7565b93506110878185602086016114a7565b61109081611656565b840191505092915050565b60006110a86018836113f7565b91506110b382611667565b602082019050919050565b60006110cb601e836113f7565b91506110d682611690565b602082019050919050565b60006110ee600f836113f7565b91506110f9826116b9565b602082019050919050565b60006111116018836113f7565b915061111c826116e2565b602082019050919050565b6000611134601a836113f7565b915061113f8261170b565b602082019050919050565b6040820160008201516111606000850182610fc8565b5060208201516111736020850182611044565b50505050565b61118281611458565b82525050565b600060208201905061119d6000830184610fd7565b92915050565b600060e0820190506111b8600083018a610fb9565b81810360208301526111ca8189611062565b905081810360408301526111de8188611062565b905081810360608301526111f28187611062565b905081810360808301526112068186611062565b905061121560a0830185611179565b61122260c0830184611179565b98975050505050505050565b60006060820190506112436000830186610fd7565b6112506020830185610faa565b61125d6040830184611179565b949350505050565b6000602082019050818103600083015261127f8184610fe6565b905092915050565b600060208201905061129c6000830184611053565b92915050565b600060208201905081810360008301526112bb8161109b565b9050919050565b600060208201905081810360008301526112db816110be565b9050919050565b600060208201905081810360008301526112fb816110e1565b9050919050565b6000602082019050818103600083015261131b81611104565b9050919050565b6000602082019050818103600083015261133b81611127565b9050919050565b60006020820190506113576000830184611179565b92915050565b6000611367611378565b9050611373828261150c565b919050565b6000604051905090565b600067ffffffffffffffff82111561139d5761139c611613565b5b6113a682611656565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600061141382611438565b9050919050565b600061142582611438565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061146d82611474565b9050919050565b600061147f82611486565b9050919050565b600061149182611438565b9050919050565b82818337600083830152505050565b60005b838110156114c55780820151818401526020810190506114aa565b838111156114d4576000848401525b50505050565b600060028204905060018216806114f257607f821691505b60208210811415611506576115056115b5565b5b50919050565b61151582611656565b810181811067ffffffffffffffff8211171561153457611533611613565b5b80604052505050565b600061154882611458565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561157b5761157a611586565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4661696c656420746f207472616e736665722066756e64730000000000000000600082015250565b7f436f757273652068617320616c7265616479206265656e20626f756768740000600082015250565b7f4e6f7420656e6f75676820635553440000000000000000000000000000000000600082015250565b7f4e65656420746f2062757920636f757273652066697273740000000000000000600082015250565b7f436f7572736520697320616c726561647920636f6d706c657465000000000000600082015250565b61173d8161142c565b811461174857600080fd5b50565b61175481611458565b811461175f57600080fd5b5056fea2646970667358221220711c4f3a410270f24afe22146328ae1be30d41cdab26bcebaf64c970e7efb1b664736f6c63430008070033
Deployed ByteCode
0x60806040526004361061007b5760003560e01c806337f66bb71161004e57806337f66bb71461013857806372bc10021461017557806387ac18601461019e578063e3a62c32146101c95761007b565b80630b91e28d146100805780630d3b4292146100c357806315876d43146100df578063194d73a21461011c575b600080fd5b34801561008c57600080fd5b506100a760048036038101906100a29190610f38565b610206565b6040516100ba97969594939291906111a3565b60405180910390f35b6100dd60048036038101906100d89190610f38565b6104b1565b005b3480156100eb57600080fd5b5061010660048036038101906101019190610f38565b610632565b6040516101139190611287565b60405180910390f35b61013660048036038101906101319190610f38565b6106c8565b005b34801561014457600080fd5b5061015f600480360381019061015a9190610f38565b610a00565b60405161016c9190611287565b60405180910390f35b34801561018157600080fd5b5061019c60048036038101906101979190610e4d565b610a68565b005b3480156101aa57600080fd5b506101b3610bb9565b6040516101c09190611342565b60405180910390f35b3480156101d557600080fd5b506101f060048036038101906101eb9190610f38565b610bc5565b6040516101fd9190611265565b60405180910390f35b60006060806060806000806000600160008a815260200190815260200160002090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160010182600201836003018460040185600501548660060154858054610273906114da565b80601f016020809104026020016040519081016040528092919081815260200182805461029f906114da565b80156102ec5780601f106102c1576101008083540402835291602001916102ec565b820191906000526020600020905b8154815290600101906020018083116102cf57829003601f168201915b505050505095508480546102ff906114da565b80601f016020809104026020016040519081016040528092919081815260200182805461032b906114da565b80156103785780601f1061034d57610100808354040283529160200191610378565b820191906000526020600020905b81548152906001019060200180831161035b57829003601f168201915b5050505050945083805461038b906114da565b80601f01602080910402602001604051908101604052809291908181526020018280546103b7906114da565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b50505050509350828054610417906114da565b80601f0160208091040260200160405190810160405280929190818152602001828054610443906114da565b80156104905780601f1061046557610100808354040283529160200191610490565b820191906000526020600020905b81548152906001019060200180831161047357829003601f168201915b50505050509250975097509750975097509750975050919395979092949650565b6104ba81610632565b6104f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f090611302565b60405180910390fd5b61050281610a00565b15610542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053990611322565b60405180910390fd5b600060026000838152602001908152602001600020905060005b818054905081101561062d573373ffffffffffffffffffffffffffffffffffffffff16828281548110610592576105916115e4565b5b9060005260206000200160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561061a5760018282815481106105f1576105f06115e4565b5b9060005260206000200160000160146101000a81548160ff02191690831515021790555061062d565b80806106259061153d565b91505061055c565b505050565b60008061063e83610bc5565b905060005b81518110156106bc573373ffffffffffffffffffffffffffffffffffffffff16828281518110610676576106756115e4565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1614156106a9576001925050506106c3565b80806106b49061153d565b915050610643565b5060009150505b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600060016000848152602001908152602001600020905061070e83610632565b1561074e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610745906112c2565b60405180910390fd5b80600501548273ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b815260040161078c9190611188565b60206040518083038186803b1580156107a457600080fd5b505afa1580156107b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dc9190610f65565b1161081c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610813906112e2565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd338360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684600501546040518463ffffffff1660e01b81526004016108819392919061122e565b602060405180830381600087803b15801561089b57600080fd5b505af11580156108af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d39190610e20565b610912576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610909906112a2565b60405180910390fd5b8060060160008154809291906109279061153d565b91905055506002600084815260200190815260200160002060405180604001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff0219169083151502179055505050505050565b600080610a0c83610bc5565b905060005b8151811015610a5c57818181518110610a2d57610a2c6115e4565b5b60200260200101516020015115610a4957600192505050610a63565b8080610a549061153d565b915050610a11565b5060009150505b919050565b6000610a746003610caa565b9050610a806003610cb8565b60006040518060e001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001888152602001878152602001868152602001858152602001848152602001828152506001600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001019080519060200190610b41929190610cce565b506040820151816002019080519060200190610b5e929190610cce565b506060820151816003019080519060200190610b7b929190610cce565b506080820151816004019080519060200190610b98929190610cce565b5060a0820151816005015560c0820151816006015590505050505050505050565b60038060000154905081565b6060600060026000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610c9b578382906000526020600020016040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff16151515158152505081526020019060010190610bfc565b50505050905080915050919050565b600081600001549050919050565b6001816000016000828254019250508190555050565b828054610cda906114da565b90600052602060002090601f016020900481019282610cfc5760008555610d43565b82601f10610d1557805160ff1916838001178555610d43565b82800160010185558215610d43579182015b82811115610d42578251825591602001919060010190610d27565b5b509050610d509190610d54565b5090565b5b80821115610d6d576000816000905550600101610d55565b5090565b6000610d84610d7f84611382565b61135d565b905082815260208101848484011115610da057610d9f611647565b5b610dab848285611498565b509392505050565b600081519050610dc281611734565b92915050565b600082601f830112610ddd57610ddc611642565b5b8135610ded848260208601610d71565b91505092915050565b600081359050610e058161174b565b92915050565b600081519050610e1a8161174b565b92915050565b600060208284031215610e3657610e35611651565b5b6000610e4484828501610db3565b91505092915050565b600080600080600060a08688031215610e6957610e68611651565b5b600086013567ffffffffffffffff811115610e8757610e8661164c565b5b610e9388828901610dc8565b955050602086013567ffffffffffffffff811115610eb457610eb361164c565b5b610ec088828901610dc8565b945050604086013567ffffffffffffffff811115610ee157610ee061164c565b5b610eed88828901610dc8565b935050606086013567ffffffffffffffff811115610f0e57610f0d61164c565b5b610f1a88828901610dc8565b9250506080610f2b88828901610df6565b9150509295509295909350565b600060208284031215610f4e57610f4d611651565b5b6000610f5c84828501610df6565b91505092915050565b600060208284031215610f7b57610f7a611651565b5b6000610f8984828501610e0b565b91505092915050565b6000610f9e838361114a565b60408301905092915050565b610fb381611462565b82525050565b610fc28161141a565b82525050565b610fd181611408565b82525050565b610fe081611408565b82525050565b6000610ff1826113c3565b610ffb81856113e6565b9350611006836113b3565b8060005b8381101561103757815161101e8882610f92565b9750611029836113d9565b92505060018101905061100a565b5085935050505092915050565b61104d8161142c565b82525050565b61105c8161142c565b82525050565b600061106d826113ce565b61107781856113f7565b93506110878185602086016114a7565b61109081611656565b840191505092915050565b60006110a86018836113f7565b91506110b382611667565b602082019050919050565b60006110cb601e836113f7565b91506110d682611690565b602082019050919050565b60006110ee600f836113f7565b91506110f9826116b9565b602082019050919050565b60006111116018836113f7565b915061111c826116e2565b602082019050919050565b6000611134601a836113f7565b915061113f8261170b565b602082019050919050565b6040820160008201516111606000850182610fc8565b5060208201516111736020850182611044565b50505050565b61118281611458565b82525050565b600060208201905061119d6000830184610fd7565b92915050565b600060e0820190506111b8600083018a610fb9565b81810360208301526111ca8189611062565b905081810360408301526111de8188611062565b905081810360608301526111f28187611062565b905081810360808301526112068186611062565b905061121560a0830185611179565b61122260c0830184611179565b98975050505050505050565b60006060820190506112436000830186610fd7565b6112506020830185610faa565b61125d6040830184611179565b949350505050565b6000602082019050818103600083015261127f8184610fe6565b905092915050565b600060208201905061129c6000830184611053565b92915050565b600060208201905081810360008301526112bb8161109b565b9050919050565b600060208201905081810360008301526112db816110be565b9050919050565b600060208201905081810360008301526112fb816110e1565b9050919050565b6000602082019050818103600083015261131b81611104565b9050919050565b6000602082019050818103600083015261133b81611127565b9050919050565b60006020820190506113576000830184611179565b92915050565b6000611367611378565b9050611373828261150c565b919050565b6000604051905090565b600067ffffffffffffffff82111561139d5761139c611613565b5b6113a682611656565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600061141382611438565b9050919050565b600061142582611438565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061146d82611474565b9050919050565b600061147f82611486565b9050919050565b600061149182611438565b9050919050565b82818337600083830152505050565b60005b838110156114c55780820151818401526020810190506114aa565b838111156114d4576000848401525b50505050565b600060028204905060018216806114f257607f821691505b60208210811415611506576115056115b5565b5b50919050565b61151582611656565b810181811067ffffffffffffffff8211171561153457611533611613565b5b80604052505050565b600061154882611458565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561157b5761157a611586565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4661696c656420746f207472616e736665722066756e64730000000000000000600082015250565b7f436f757273652068617320616c7265616479206265656e20626f756768740000600082015250565b7f4e6f7420656e6f75676820635553440000000000000000000000000000000000600082015250565b7f4e65656420746f2062757920636f757273652066697273740000000000000000600082015250565b7f436f7572736520697320616c726561647920636f6d706c657465000000000000600082015250565b61173d8161142c565b811461174857600080fd5b50565b61175481611458565b811461175f57600080fd5b5056fea2646970667358221220711c4f3a410270f24afe22146328ae1be30d41cdab26bcebaf64c970e7efb1b664736f6c63430008070033