Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 218 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw Bonus | 12485383 | 1268 days ago | IN | 0 ETH | 0.00403805 | ||||
Sell | 12370712 | 1285 days ago | IN | 0 ETH | 0.00853367 | ||||
Sell | 12365646 | 1286 days ago | IN | 0 ETH | 0.00651558 | ||||
Invest | 12360785 | 1287 days ago | IN | 0 ETH | 0.00472417 | ||||
Buy | 12360080 | 1287 days ago | IN | 0 ETH | 0.0155027 | ||||
Withdraw Bonus | 12360028 | 1287 days ago | IN | 0 ETH | 0.00423892 | ||||
Invest | 12360026 | 1287 days ago | IN | 0 ETH | 0.00569514 | ||||
Withdraw Bonus | 12360020 | 1287 days ago | IN | 0 ETH | 0.00426541 | ||||
Invest | 12360017 | 1287 days ago | IN | 0 ETH | 0.00583405 | ||||
Sell | 12359975 | 1287 days ago | IN | 0 ETH | 0.01125802 | ||||
Buy | 12359963 | 1287 days ago | IN | 0 ETH | 0.01018595 | ||||
Sell | 12359955 | 1287 days ago | IN | 0 ETH | 0.00651066 | ||||
Sell | 12358907 | 1287 days ago | IN | 0 ETH | 0.00750226 | ||||
Sell | 12358901 | 1287 days ago | IN | 0 ETH | 0.00651066 | ||||
Sell | 12351256 | 1288 days ago | IN | 0 ETH | 0.00456808 | ||||
Buy | 12341783 | 1290 days ago | IN | 0 ETH | 0.00751365 | ||||
Buy | 12341763 | 1290 days ago | IN | 0 ETH | 0.00970205 | ||||
Sell | 12340163 | 1290 days ago | IN | 0 ETH | 0.00671432 | ||||
Buy | 12340161 | 1290 days ago | IN | 0 ETH | 0.00956091 | ||||
Buy | 12340156 | 1290 days ago | IN | 0 ETH | 0.01127389 | ||||
Sell | 12327501 | 1292 days ago | IN | 0 ETH | 0.00900702 | ||||
Buy | 12327498 | 1292 days ago | IN | 0 ETH | 0.01036701 | ||||
Invest | 12326819 | 1292 days ago | IN | 0 ETH | 0.00472417 | ||||
Invest | 12324874 | 1292 days ago | IN | 0 ETH | 0.0069591 | ||||
Buy | 12322030 | 1293 days ago | IN | 0 ETH | 0.01212525 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
EthStonks
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-03-27 */ // // -/oyhhhhhdddddhys+/:` // -sddyo+//////++ossssyyhdho- // -yds/:-------:::/+oo++++++oydh/` // `sms/-----....---::/+++++++++/+ohd+` // -dh+--------...----://++++++//////+yd+` // /my:-..------..-----::/++++++/////:::+hh- // /my:...---:::..-----:::/+++++///:::::---sm: // `md+:-..--:::---::::::::/oo++//:::------..om: // /Nhhys/---:+syysso/::::/+oo++//:-..........sm- // -mysy++o:-:+o+o+//+o/-::/+oo++//:-..`````...-dh` // yd:+s+:/::::--:+ho::/-:/+ooo+++/::-...````...oN- // .Ny:::-::/:---..-::...-:+osooo++///:---.......+N- // -Ny/:--::/-----.....---+osoooo++++//::::::---.+N- // .Nh+/:::::--::---:::::/osssooo+++++//////:::--/N: // `Ndo+/::::-:::::::////+ossssooo+++++///////::-/N/ // ymoo/:::-://////////+ossssssoooooo++++++++//:/N/ // smsoosyyso+////////+oosssssssoooooo++++++++//+N: // sNs+//syyy+///////++ossssssssssssooooooooo+++yN- // +Nyo+/:+so+///////+oossssyyssssssssoooooooooomy // `mdossssossss+///+oossssyyyysssssssssssssooodm- // /Ns::+syso+///++oossssyyyyyyyyyyssssssssssym+ // `dd/-.-::::/+++ossssyyyyyyyyyyyyyssssssssyms // smo----::/++ossssyyyyyhhhhyyyyyyssssssssmh` // :Ny:/::/+oossyyyyyyhhhhhhyyhyyysssooossdh. // `smso++ossyyyhhhdddddhhyyyyyyysssoooosdm. // /dddhhhhhddmmmmmdhhyyyyyyyssoooooooym: // `-//+yNdmddhhhhyyyyssyyyssooo+++o++d. // :Nmdhhyyyysssssssssooo+++++/:-oh+. // `-ohNmhhyyyssssssssssoo+++///:----hmmy- // ./ymNNNs+oyyysssssooossoo++//::-....ommmmms. // `:ohmNNNNN+:/++sssssooooooo+//:--......-ydddmmmms. // ./ymNmmmmmmNo---:/+ooooo++++/:--..........oddddmdddmmdyo:. // dmmmmmmmmmmNh-....-/oso:--....````........oddddddddddmddhddd // mddddmmmmmmN:..-/yhhhyyys+-```````````...odddddddddddmmddhhh // __ __ __ __ // ___ / /_/ /_ _____/ /_____ ____ / /_______ // / _ \/ __/ __ \ / ___/ __/ __ \/ __ \/ //_/ ___/ // / __/ /_/ / / / (__ ) /_/ /_/ / / / / ,< (__ ) // \___/\__/_/ /_/ /____/\__/\____/_/ /_/_/|_/____/ // // created by Mr F // HTML/CSS and Graphics by Karl // Advanced Solidity by ToCsIcK // // https://ethstonks.finance/ // https://discord.gg/mDMyTksceR // https://t.me/ethstonks // pragma solidity 0.7.6; pragma experimental ABIEncoderV2; // File: contracts/EthStonks.sol contract EthStonks { using SafeMath for uint; modifier onlyAdmin() { require(msg.sender == admin); _; } modifier preMarketOpen() { require(block.timestamp < PREMARKET_LENGTH + round[r].seedTime, "premarket closed"); _; } modifier preMarketClosed() { require(block.timestamp > PREMARKET_LENGTH + round[r].seedTime, "premarket open"); _; } modifier checkDeposit(uint amount) { require(amount >= MIN_BUY, "min buy"); require(token.allowance(msg.sender, address(this)) >= amount, "no allowance"); require(token.balanceOf(msg.sender) >= amount, "no funds"); _; } modifier hasName() { require(bytes(addressToName[msg.sender]).length > 0, "no name"); _; } modifier validName(string memory name) { uint length = nameLength(name); require(length <= 12); require(length >= 3); require(checkCharacters(bytes(name))); _; } modifier updatePlayerIndex() { Round storage _round = round[r]; if (_round.addrToId[msg.sender] == 0) { _round.addrToId[msg.sender] = _round.playerIndex; _round.idToAddr[_round.playerIndex++] = msg.sender; } _; } modifier recordGas() { uint gas; if (enableGas) { gas = gasleft(); } _; if (enableGas) { _recordGas(gas); } } address private admin; address private stonkRevenueService; uint constant private PSN = 10000; uint constant private PSNH = 5000; uint constant private INVEST_RATIO = 86400; uint constant private MARKET_RESET = 864000000000; uint constant private CB_ONE = 1e16; uint constant private CB_TWO = 1e25; uint constant private CB_THREE = 1e37; uint32 constant private RND_MAX = 72 hours; uint32 constant private PREMARKET_LENGTH = 24 hours; uint8 constant private FEE = 20; uint constant public MIN_BUY = 1e6; uint constant public BROKER_REQ = 1000e6; uint constant public MIN_NFT_BUY = 100e6; struct Round { mapping(uint => address) idToAddr; mapping(address => uint) addrToId; uint seedBalance; uint preMarketSpent; uint preMarketDivs; uint stonkMarket; address spender; address prod; address chadBroker; mapping(int8 => address) lastBuys; uint bailoutFund; uint nextCb; uint32 playerIndex; uint32 seedTime; uint32 end; uint16 index; int8 lastBuyIndex; } struct PlayerRound { // management uint preMarketSpent; uint lastAction; uint companies; uint oldRateStonks; // record keeping uint spent; uint stonkDivs; uint cashbackDivs; uint brokerDivs; uint brokeredTrades; uint bailoutDivs; uint chadBrokerDivs; uint gasSpent; } struct Player { bool isBroker; string lastBroker; uint preMarketDivsWithdrawn; uint availableDivs; mapping(uint => PlayerRound) playerRound; } struct BailoutEvent { string prod; string spender; string b1; string b2; string b3; string b4; string b5; uint round; uint cb; uint amount; } mapping(address => string) public addressToName; mapping(string => address) public nameToAddress; mapping(address => Player) internal player; mapping(uint => Round) internal round; uint public r = 1; uint public pmDivBal; // needs to be separate because it is dynamic for users uint public divBal; // includes bailouts, cashback, broker divs and stonk sales uint public devBal; // dev fee balance 😊 string private featuredBroker = 'MrF'; TokenInterface private token; EthStonksLibrary private lib; AggregatorV3Interface internal priceFeed; StonkNFT internal nft; bool public enableGas = true; event LogPreMarketBuy(string name, string broker, uint value, bool isBroker, bool validBroker); event LogBuy(string name, string broker, uint value, bool isBroker, bool validBroker); event LogInvest(string name, uint value); event LogSell(string name, uint value); event LogWithdraw(string name, uint value); event LogHistory(uint index, uint fund, uint market, uint timestamp); event LogBailouts(BailoutEvent e); event NewPlayer(address addr, string name); event NewBroker(string name); event NewChad(string name, uint divs, uint trades); event NewRound(uint endBlock); // CONSTRUCTOR / ADMIN constructor(address _tokenAddress, address _stonkRevenueService, uint32 _open, EthStonksLibrary _lib, address _priceFeed, StonkNFT _nft) updatePlayerIndex { nft = _nft; lib = _lib; token = TokenInterface(_tokenAddress); stonkRevenueService = _stonkRevenueService; admin = msg.sender; addressToName[admin] = 'MrF'; nameToAddress['MrF'] = admin; round[r].chadBroker = admin; round[r].seedTime = _open - PREMARKET_LENGTH; round[r].stonkMarket = MARKET_RESET; round[r].end = _open + RND_MAX; round[r].nextCb = CB_ONE; // Main net ETH / USDT address = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419 priceFeed = AggregatorV3Interface(_priceFeed); } function setStonkRevenueService(address addr) external onlyAdmin { stonkRevenueService = addr; } function setGasFlag(bool val) external onlyAdmin { enableGas = val; } function seedMarket(uint amount) external checkDeposit(amount) onlyAdmin preMarketOpen { address(lib).delegatecall(abi.encodeWithSignature('seedMarket(uint256)', amount)); } function grantBroker(address addr) external onlyAdmin { player[addr].isBroker = true; emit NewBroker(addressToName[addr]); } function claimBroker(uint8 _v, bytes32 _r, bytes32 _s) public { // Prevent multiple calls require(!player[msg.sender].isBroker); // Confirm the hash was signed by admin bytes memory prefix = "\x19Ethereum Signed Message:\n32"; // Confirm the hash contains the correct data uint256 chainId; assembly { chainId := chainid() } string memory checkMessage = string(abi.encodePacked("Grant stonkbroker to ", toString(msg.sender), " on chain ", toString(chainId))); bytes32 checkHash = keccak256(abi.encodePacked(checkMessage)); bytes memory message = abi.encodePacked(prefix, checkHash); bytes32 prefixedHash = keccak256(message); address recoveredAddress = ecrecover(prefixedHash, _v, _r, _s); require(recoveredAddress == admin, string(abi.encodePacked("Recovered address was ", recoveredAddress))); // This is a legit request player[msg.sender].isBroker = true; emit NewBroker(addressToName[msg.sender]); } function featureBroker(string calldata _featuredBroker) external onlyAdmin { featuredBroker = _featuredBroker; } function devWithdraw() external onlyAdmin { require(devBal > 0); token.approve(stonkRevenueService, devBal); devBal = 0; StonkRevenueServiceInterface(stonkRevenueService).withdraw(address(token)); } // USER FUNCTIONS function preMarketBuy(uint _amount, string calldata _broker) external checkDeposit(_amount) preMarketOpen hasName recordGas { address(lib).delegatecall(abi.encodeWithSignature('preMarketBuy(uint256,string)', _amount, _broker)); if (r == 1) { if (_amount >= MIN_NFT_BUY) { nft.mintPreMarket(msg.sender, round[1].addrToId[msg.sender]); } } } function buy(uint _amount, string calldata _broker) external checkDeposit(_amount) preMarketClosed hasName recordGas { address(lib).delegatecall(abi.encodeWithSignature('buy(uint256,string)', _amount, _broker)); if (r == 1) { if (_amount >= MIN_NFT_BUY) { nft.mint(msg.sender, round[1].addrToId[msg.sender]); } } } function invest() external preMarketClosed hasName recordGas { address(lib).delegatecall(abi.encodeWithSignature('invest()')); } function sell() external preMarketClosed hasName recordGas { address(lib).delegatecall(abi.encodeWithSignature('sell()')); } function withdrawBonus() external recordGas { address(lib).delegatecall(abi.encodeWithSignature('withdrawBonus()')); } // CURRENT ROUND VIEW FUNCTIONS function stonkNames(address addr) public view returns (string memory _name, string memory _broker, string memory _featuredBroker, string memory _spender, string memory _producer, string memory _chad) { address spender = round[r].spender; address prod = round[r].prod; address chad = round[r].chadBroker; string memory broker; if (player[addr].isBroker) { broker = addressToName[addr]; } else { broker = player[addr].lastBroker; } return ( addressToName[addr], broker, featuredBroker, addressToName[spender], addressToName[prod], addressToName[chad] ); } function stonkNumbers(address addr, uint buyAmount) public returns (uint companies, uint stonks, uint receiveBuy, uint receiveSell, uint dividends) { (, bytes memory result) = address(lib).delegatecall(abi.encodeWithSignature('stonkNumbers(address,uint256)', addr, buyAmount)); return abi.decode(result, (uint, uint, uint, uint, uint)); } function gameData() external returns (uint rnd, uint index, uint open, uint end, uint fund, uint market, uint bailout) { (, bytes memory result) = address(lib).delegatecall(abi.encodeWithSignature('gameData()')); return abi.decode(result, (uint, uint, uint, uint, uint, uint, uint)); } function lastBuy(uint rnd, int8 index) external view returns (address) { return round[rnd].lastBuys[index]; } // HISTORICAL VIEW FUNCTIONS function userRoundStats(address addr, uint rnd) public view returns (uint, uint, uint, uint, uint, uint, uint, uint, uint) { PlayerRound memory _playerRound = player[addr].playerRound[rnd]; return ( _playerRound.spent, calculatePreMarketDivs(addr, rnd), _playerRound.stonkDivs, _playerRound.cashbackDivs, _playerRound.brokerDivs, _playerRound.brokeredTrades, _playerRound.bailoutDivs, _playerRound.chadBrokerDivs, _playerRound.gasSpent ); } function calculatePreMarketDivs(address addr, uint rnd) public view returns (uint) { if (player[addr].playerRound[rnd].preMarketSpent == 0) { return 0; } uint totalDivs = round[rnd].preMarketDivs; uint totalSpent = round[rnd].preMarketSpent; uint playerSpent = player[addr].playerRound[rnd].preMarketSpent; uint playerDivs = (((playerSpent * 2 ** 64) / totalSpent) * totalDivs) / 2 ** 64; return playerDivs; } function getAddrById(uint rnd, uint ind) public view returns (address) { return round[rnd].idToAddr[ind]; } function getIdByAddr(uint rnd, address addr) public view returns (uint) { return round[rnd].addrToId[addr]; } function getRoundIndex(uint rnd) public view returns (uint) { return round[rnd].index; } function getPlayerMetric(address addr, uint rnd, uint key) public view returns (uint) { if (key == 0) { return player[addr].playerRound[rnd].preMarketSpent; } else if (key == 1) { return player[addr].playerRound[rnd].lastAction; } else if (key == 2) { return player[addr].playerRound[rnd].companies; } else if (key == 3) { return player[addr].playerRound[rnd].oldRateStonks; } else if (key == 4) { return player[addr].playerRound[rnd].spent; } else if (key == 5) { return player[addr].playerRound[rnd].stonkDivs; } else if (key == 6) { return player[addr].playerRound[rnd].cashbackDivs; } else if (key == 7) { return player[addr].playerRound[rnd].brokerDivs; } else if (key == 8) { return player[addr].playerRound[rnd].brokeredTrades; } else if (key == 9) { return player[addr].playerRound[rnd].bailoutDivs; } else if (key == 10) { return player[addr].playerRound[rnd].chadBrokerDivs; } else if (key == 11) { return player[addr].preMarketDivsWithdrawn; } else if (key == 12) { return player[addr].availableDivs; } else if (key == 13) { return player[addr].playerRound[rnd].gasSpent; } else if (key == 14) { return player[addr].isBroker ? 1 : 0; } else { return 0; } } function leaderNumbers() public returns (uint, uint, uint, uint, uint, uint, uint) { (, bytes memory result) = address(lib).delegatecall(abi.encodeWithSignature('leaderNumbers()')); return abi.decode(result, (uint, uint, uint, uint, uint, uint, uint)); } function getRoundMetric(uint rnd, uint key) public view returns (uint) { if (key == 0) { return round[rnd].playerIndex; } else if (key == 1) { return round[rnd].index; } else if (key == 2) { return round[rnd].seedTime; } else if (key == 3) { return round[rnd].seedBalance; } else if (key == 4) { return round[rnd].preMarketSpent; } else if (key == 5) { return round[rnd].preMarketDivs; } else if (key == 6) { return round[rnd].end; } else if (key == 7) { return round[rnd].stonkMarket; } else if (key == 8) { return round[rnd].bailoutFund; } else if (key == 9) { return round[rnd].nextCb; } else { return 0; } } function getRoundLastBuyIndex(uint rnd) external view returns (int8) { return round[rnd].lastBuyIndex; } // INTERNAL FUNCTIONS (THAT MODIFY STATE) function _recordGas(uint gas) internal { (,int price,,,) = priceFeed.latestRoundData(); // There is some computation before and after the first and last call to gasleft(), 58000 is an approximation of this amount // Ether = 1e18, price feed = 1e8, gasSpent = 1e6 (18 + 8 - 6) = 20 player[msg.sender].playerRound[r].gasSpent += ((gas - gasleft() + 58000) * tx.gasprice) * uint(price) / 1e20; } // INTERNAL FUNCTIONS (STATE NOT MODIFIED) function calculatePreMarketOwned(address addr) internal view returns (uint) { if (player[addr].playerRound[r].preMarketSpent == 0) { return 0; } uint stonks = calculateTrade(round[r].preMarketSpent, round[r].seedBalance, MARKET_RESET); uint stonkFee = (stonks * FEE) / 100; stonks -= stonkFee; uint totalSpentBig = round[r].preMarketSpent * 100; // inflate for precision uint userPercent = stonks / (totalSpentBig / player[addr].playerRound[r].preMarketSpent); return (userPercent * 100) / INVEST_RATIO; } function userRoundEarned(address addr, uint rnd) internal view returns (uint earned) { PlayerRound memory _playerRound = player[addr].playerRound[rnd]; earned += calculatePreMarketDivs(addr, rnd); earned += _playerRound.stonkDivs; earned += _playerRound.cashbackDivs; earned += _playerRound.brokerDivs; earned += _playerRound.bailoutDivs; earned += _playerRound.chadBrokerDivs; } function marketFund() internal view returns (uint) { return token.balanceOf(address(this)) - (round[r].bailoutFund + divBal + pmDivBal + devBal); } function calculateTrade(uint rt, uint rs, uint bs) internal pure returns (uint) { return PSN.mul(bs) / PSNH.add(PSN.mul(rs).add(PSNH.mul(rt)) / rt); } function calculateSell(uint stonks) internal view returns (uint) { uint received = calculateTrade(stonks, round[r].stonkMarket, marketFund()); uint fee = (received * FEE) / 100; return (received - fee); } function calculateBuy(uint spent) internal view returns (uint) { uint stonks = calculateTrade(spent, marketFund(), round[r].stonkMarket); uint stonkFee = (stonks * FEE) / 100; return (stonks - stonkFee); } // USERNAME FUNCTIONS function checkName(string calldata name) external view returns (bool) { uint length = nameLength(name); if (length < 3 || length > 12) { return false; } if (checkCharacters(bytes(name))) { return (nameToAddress[name] == address(0)); } return false; } function registerName(string calldata name) public updatePlayerIndex validName(name) { // Name is not yet registered require(nameToAddress[name] == address(0)); // No name changes allowed require(bytes(addressToName[msg.sender]).length == 0); addressToName[msg.sender] = name; nameToAddress[name] = msg.sender; } function registerNameAndClaim(string calldata name, uint8 _v, bytes32 _r, bytes32 _s) external { registerName(name); claimBroker(_v, _r, _s); } function checkCharacters(bytes memory name) internal pure returns (bool) { // Check for only letters and numbers for (uint i; i < name.length; i++) { bytes1 char = name[i]; if ( !(char >= 0x30 && char <= 0x39) && //9-0 !(char >= 0x41 && char <= 0x5A) && //A-Z !(char >= 0x61 && char <= 0x7A) //a-z ) return false; } return true; } function nameLength(string memory _str) public pure returns (uint length) { uint i = 0; bytes memory string_rep = bytes(_str); while (i < string_rep.length) { if (uint8(string_rep[i] >> 7) == 0) i += 1; else if (uint8(string_rep[i] >> 5) == 0x6) i += 2; else if (uint8(string_rep[i] >> 4) == 0xE) i += 3; else if (uint8(string_rep[i] >> 3) == 0x1E) i += 4; else //For safety i += 1; length++; } } function toString(address account) public pure returns (string memory) { return toString(abi.encodePacked(account)); } function toString(uint256 value) public pure returns (string memory) { return toString(abi.encodePacked(value)); } function toString(bytes memory data) public pure returns (string memory) { bytes memory alphabet = "0123456789abcdef"; bytes memory str = new bytes(2 + data.length * 2); str[0] = "0"; str[1] = "x"; for (uint i = 0; i < data.length; i++) { str[2 + i * 2] = alphabet[uint(uint8(data[i] >> 4))]; str[3 + i * 2] = alphabet[uint(uint8(data[i] & 0x0f))]; } return string(str); } } interface StonkRevenueServiceInterface { function withdraw(address tokenAddress) external; } // File: @chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); } // File: @openzeppelin/contracts/introspection/IERC165.sol /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/introspection/ERC165.sol /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () internal { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } } // File: @openzeppelin/contracts/utils/Context.sol /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; } // File: @openzeppelin/contracts/token/ERC721/IERC721Metadata.sol /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); } // File: @openzeppelin/contracts/math/SafeMath.sol /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } } // File: @openzeppelin/contracts/utils/Address.sol /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/utils/EnumerableSet.sol /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File: @openzeppelin/contracts/utils/EnumerableMap.sol /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct MapEntry { bytes32 _key; bytes32 _value; } struct Map { // Storage of map keys and values MapEntry[] _entries; // Position of the entry defined by a key in the `entries` array, plus 1 // because index 0 means a key is not in the map. mapping (bytes32 => uint256) _indexes; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) { // Equivalent to !contains(map, key) map._entries.push(MapEntry({ _key: key, _value: value })); // The entry is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value map._indexes[key] = map._entries.length; return true; } else { map._entries[keyIndex - 1]._value = value; return false; } } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex != 0) { // Equivalent to contains(map, key) // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one // in the array, and then remove the last entry (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = keyIndex - 1; uint256 lastIndex = map._entries.length - 1; // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. MapEntry storage lastEntry = map._entries[lastIndex]; // Move the last entry to the index where the entry to delete is map._entries[toDeleteIndex] = lastEntry; // Update the index for the moved entry map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved entry was stored map._entries.pop(); // Delete the index for the deleted slot delete map._indexes[key]; return true; } else { return false; } } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._indexes[key] != 0; } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._entries.length; } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { require(map._entries.length > index, "EnumerableMap: index out of bounds"); MapEntry storage entry = map._entries[index]; return (entry._key, entry._value); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key) return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {_tryGet}. */ function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } } // File: @openzeppelin/contracts/utils/Strings.sol /** * @dev String operations. */ library Strings { /** * @dev Converts a `uint256` to its ASCII `string` 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); uint256 index = digits - 1; temp = value; while (temp != 0) { buffer[index--] = bytes1(uint8(48 + temp % 10)); temp /= 10; } return string(buffer); } } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using SafeMath for uint256; using Address for address; using EnumerableSet for EnumerableSet.UintSet; using EnumerableMap for EnumerableMap.UintToAddressMap; using Strings for uint256; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from holder address to their (enumerable) set of owned tokens mapping (address => EnumerableSet.UintSet) private _holderTokens; // Enumerable mapping from token ids to their owners EnumerableMap.UintToAddressMap private _tokenOwners; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; // Token name string private _name; // Token symbol string private _symbol; // Optional mapping for token URIs mapping (uint256 => string) private _tokenURIs; // Base URI string private _baseURI; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor (string memory name_, string memory symbol_) public { _name = name_; _symbol = symbol_; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); _registerInterface(_INTERFACE_ID_ERC721_METADATA); _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _holderTokens[owner].length(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI. return string(abi.encodePacked(base, tokenId.toString())); } /** * @dev Returns the base URI set via {_setBaseURI}. This will be * automatically added as a prefix in {tokenURI} to each token's URI, or * to the token ID if no specific URI is set for that token ID. */ function baseURI() public view virtual returns (string memory) { return _baseURI; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { return _holderTokens[owner].at(index); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds return _tokenOwners.length(); } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { (uint256 tokenId, ) = _tokenOwners.at(index); return tokenId; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _tokenOwners.contains(tokenId); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: d* * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); // internal owner _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); // Clear metadata (if any) if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } _holderTokens[owner].remove(tokenId); _tokenOwners.remove(tokenId); emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _holderTokens[from].remove(tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(from, to, tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev Internal function to set the base URI for all token IDs. It is * automatically added as a prefix to the value returned in {tokenURI}, * or to the token ID if {tokenURI} is empty. */ function _setBaseURI(string memory baseURI_) internal virtual { _baseURI = baseURI_; } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) { if (!to.isContract()) { return true; } bytes memory returndata = to.functionCall(abi.encodeWithSelector( IERC721Receiver(to).onERC721Received.selector, _msgSender(), from, tokenId, _data ), "ERC721: transfer to non ERC721Receiver implementer"); bytes4 retval = abi.decode(returndata, (bytes4)); return (retval == _ERC721_RECEIVED); } function _approve(address to, uint256 tokenId) private { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { } } // File: @openzeppelin/contracts/utils/Counters.sol /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. 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;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; 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 { // The {SafeMath} overflow check can be skipped here, see the comment at the top counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } } // File: @openzeppelin/contracts/access/Ownable.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 () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), 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 { emit OwnershipTransferred(_owner, address(0)); _owner = 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"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: contracts/StonkNFT.sol contract StonkNFT is ERC165, ERC721 { using Strings for uint256; mapping(address => bool) hasMintedPreMarket; mapping(address => bool) hasMinted; address public owner; address private stonk; constructor() ERC721("StonkNFT", "SNFT") { // Owner owner = msg.sender; // Set base URI for token metadata _setBaseURI("https://ethstonks.finance/meta/"); } function setStonk(address _stonk) public { require(msg.sender == owner); stonk = _stonk; } function mintPreMarket(address player, uint playerId) public { // Only Stonks contract can mint require(msg.sender == address(stonk)); // Check if player has already minted and record if (hasMintedPreMarket[player]) { return; } hasMintedPreMarket[player] = true; // Grab player's ID from stonk contract uint id = uint256(keccak256(abi.encodePacked("premarket_", playerId))); // Mint and set metadata URI _safeMint(player, id); _setTokenURI(id, string(abi.encodePacked("live/premarket/", playerId.toString()))); } function mint(address player, uint playerId) public { // Only Stonks contract can mint require(msg.sender == address(stonk)); // Check if player has already minted and record if (hasMinted[player]) { return; } hasMinted[player] = true; // Grab player's ID from stonk contract uint id = uint256(keccak256(abi.encodePacked("main_", playerId))); // Mint and set metadata URI _safeMint(player, id); _setTokenURI(id, string(abi.encodePacked("live/main/", playerId.toString()))); } function mintRopstenBeta(address player, uint playerId) public { require(msg.sender == owner); // Grab player's ID from stonk contract uint id = uint256(keccak256(abi.encodePacked("ropsten_", playerId))); // Mint and set metadata URI _safeMint(player, id); _setTokenURI(id, string(abi.encodePacked("beta/ropsten/", playerId.toString()))); } function mintRinkebyBeta(address player, uint playerId) public { require(msg.sender == owner); // Grab player's ID from stonk contract uint id = uint256(keccak256(abi.encodePacked("rinkeby_", playerId))); // Mint and set metadata URI _safeMint(player, id); _setTokenURI(id, string(abi.encodePacked("beta/rinkeby/", playerId.toString()))); } } // File: contracts/TokenInterface.sol interface TokenInterface { function name() external returns (string memory); function symbol() external returns (string memory); function decimals() external returns (uint); function totalSupply() external view returns (uint); function balanceOf(address who) external view returns (uint); function transfer(address to, uint value) external; event Transfer(address indexed from, address indexed to, uint value); function allowance(address owner, address spender) external view returns (uint); function transferFrom(address from, address to, uint value) external; function approve(address spender, uint value) external; event Approval(address indexed owner, address indexed spender, uint value); } // File: contracts/EthStonksLibrary.sol contract EthStonksLibrary { using SafeMath for uint; address private admin; address private stonkRevenueService; uint constant private PSN = 10000; uint constant private PSNH = 5000; uint constant private INVEST_RATIO = 86400; uint constant private MARKET_RESET = 864000000000; uint constant private CB_ONE = 1e16; uint constant private CB_TWO = 1e25; uint constant private CB_THREE = 1e37; uint32 constant private RND_MAX = 72 hours; uint32 constant private PREMARKET_LENGTH = 24 hours; uint8 constant private FEE = 20; uint constant public MIN_BUY = 1e6; uint constant public BROKER_REQ = 1000e6; uint constant public MIN_NFT_BUY = 100e6; struct Round { mapping(uint => address) idToAddr; mapping(address => uint) addrToId; uint seedBalance; uint preMarketSpent; uint preMarketDivs; uint stonkMarket; address spender; address prod; address chadBroker; mapping(int8 => address) lastBuys; uint bailoutFund; uint nextCb; uint32 playerIndex; uint32 seedTime; uint32 end; uint16 index; int8 lastBuyIndex; } struct PlayerRound { // management uint preMarketSpent; uint lastAction; uint companies; uint oldRateStonks; // record keeping uint spent; uint stonkDivs; uint cashbackDivs; uint brokerDivs; uint brokeredTrades; uint bailoutDivs; uint chadBrokerDivs; uint gasSpent; } struct Player { bool isBroker; string lastBroker; uint preMarketDivsWithdrawn; uint availableDivs; mapping(uint => PlayerRound) playerRound; } struct BailoutEvent { string prod; string spender; string b1; string b2; string b3; string b4; string b5; uint round; uint cb; uint amount; } mapping(address => string) public addressToName; mapping(string => address) public nameToAddress; mapping(address => Player) internal player; mapping(uint => Round) internal round; uint public r = 1; uint public pmDivBal; // needs to be separate because it is dynamic for users uint public divBal; // includes bailouts, cashback, broker divs and stonk sales uint public devBal; // dev fee balance 😊 string private featuredBroker = 'MrF'; TokenInterface private token; AggregatorV3Interface internal priceFeed; StonkNFT internal nft; bool public enableGas = true; event LogPreMarketBuy(string name, string broker, uint value, bool isBroker, bool validBroker); event LogBuy(string name, string broker, uint value, bool isBroker, bool validBroker); event LogInvest(string name, uint value); event LogSell(string name, uint value); event LogWithdraw(string name, uint value); event LogHistory(uint index, uint fund, uint market, uint timestamp); event LogBailouts(BailoutEvent e); event NewPlayer(address addr, string name); event NewBroker(string name); event NewChad(string name, uint divs, uint trades); event NewRound(uint endBlock); function seedMarket(uint amount) external { token.transferFrom(msg.sender, address(this), amount); round[r].seedBalance += amount; writeHistory(); } function preMarketBuy(uint _amount, string calldata _broker) public { address addr = msg.sender; address brokerAddr = nameToAddress[_broker]; bool validBroker = false; Round storage _round = round[r]; Player storage _player = player[addr]; PlayerRound storage _playerRound = player[addr].playerRound[r]; _round.preMarketSpent += _amount; _round.stonkMarket = preStonkMarket(_round.preMarketSpent); // no production until premarket ends _playerRound.lastAction = PREMARKET_LENGTH + round[r].seedTime; _playerRound.preMarketSpent += _amount; _playerRound.spent += _amount; if (_playerRound.spent > player[_round.spender].playerRound[r].spent) { _round.spender = addr; // only during premarket _round.prod = addr; } if (!_player.isBroker && _playerRound.spent >= BROKER_REQ) { _player.isBroker = true; emit NewBroker(addressToName[addr]); } if (_player.isBroker) {// if user is a broker, they get 10% back divBal += _amount / 10; _player.availableDivs += _amount / 10; _playerRound.cashbackDivs += _amount / 10; } else if (player[brokerAddr].isBroker && brokerAddr != addr) {// or if valid broker, 5% each validBroker = true; divBal += _amount / 10; _player.lastBroker = _broker; _player.availableDivs += _amount / 20; _playerRound.cashbackDivs += _amount / 20; player[brokerAddr].availableDivs += _amount / 20; player[brokerAddr].playerRound[r].brokerDivs += _amount / 20; player[brokerAddr].playerRound[r].brokeredTrades++; } if (validBroker) { updateChadBroker(brokerAddr); } token.transferFrom(addr, address(this), _amount); feeSplit((_amount * FEE) / 100); updateLastBuyer(); writeHistory(); emit LogPreMarketBuy(addressToName[addr], _broker, _amount, _player.isBroker, validBroker); } function buy(uint _amount, string calldata _broker) external { address addr = msg.sender; address brokerAddr = nameToAddress[_broker]; bool validBroker = false; if (block.timestamp > round[r].end) {// market crash incrementRound(); preMarketBuy(_amount, _broker); return; } if (round[r].stonkMarket > round[r].nextCb) { bool roundOver = handleCircuitBreaker(); if (roundOver) { preMarketBuy(_amount, _broker); return; } } Round storage _round = round[r]; Player storage _player = player[addr]; PlayerRound storage _playerRound = player[addr].playerRound[r]; _playerRound.spent += _amount; if (_playerRound.spent > player[_round.spender].playerRound[r].spent) { _round.spender = addr; } if (!_player.isBroker && _playerRound.spent >= BROKER_REQ) { _player.isBroker = true; emit NewBroker(addressToName[addr]); } if (_player.isBroker) {// if user is a broker, they get 10% back divBal += _amount / 10; _player.availableDivs += _amount / 10; _playerRound.cashbackDivs += _amount / 10; } else if (player[brokerAddr].isBroker && brokerAddr != addr) {// or if valid broker, 5% each validBroker = true; divBal += _amount / 10; _player.lastBroker = _broker; _player.availableDivs += _amount / 20; _playerRound.cashbackDivs += _amount / 20; player[brokerAddr].availableDivs += _amount / 20; player[brokerAddr].playerRound[r].brokerDivs += _amount / 20; player[brokerAddr].playerRound[r].brokeredTrades++; } uint companies = _playerRound.companies.add(calculatePreMarketOwned(addr)); _playerRound.oldRateStonks += companies.mul(block.timestamp - _playerRound.lastAction); _playerRound.lastAction = block.timestamp; _playerRound.companies += calculateBuy(_amount) / INVEST_RATIO; if (_playerRound.companies > getCompanies(_round.prod)) { _round.prod = addr; } _round.stonkMarket += (calculateBuy(_amount) / 10); if (validBroker) { updateChadBroker(brokerAddr); } token.transferFrom(addr, address(this), _amount); feeSplit((_amount * FEE) / 100); incrementTimer(_amount); updateLastBuyer(); writeHistory(); emit LogBuy(addressToName[addr], _broker, _amount, _player.isBroker, validBroker); } function sell() external { if (block.timestamp > round[r].end) {// market crash incrementRound(); return; } if (round[r].stonkMarket > round[r].nextCb) { bool roundOver = handleCircuitBreaker(); if (roundOver) { return; } } address addr = msg.sender; uint stonks = getStonks(addr); require(stonks > 0); uint received = calculateTrade(stonks, round[r].stonkMarket, marketFund()); uint fee = (received * FEE) / 100; received -= fee; player[addr].playerRound[r].lastAction = block.timestamp; player[addr].playerRound[r].oldRateStonks = 0; player[addr].playerRound[r].stonkDivs += received; player[addr].availableDivs += received; divBal += received; round[r].stonkMarket += stonks; feeSplit(fee); writeHistory(); emit LogSell(addressToName[addr], received); withdrawBonus(); // gas is expensive } function handleCircuitBreaker() public returns (bool) { if (round[r].stonkMarket > CB_THREE) { payBailouts(3, round[r].bailoutFund); incrementRound(); return true; } uint pool = round[r].bailoutFund / 3; round[r].bailoutFund -= pool; if (round[r].stonkMarket > CB_TWO) { round[r].nextCb = CB_THREE; payBailouts(2, pool); return false; } // only other option is CB 1 round[r].nextCb = CB_TWO; payBailouts(1, pool); return false; } function incrementRound() public { r++; round[r].stonkMarket = MARKET_RESET; round[r].seedTime = uint32(block.timestamp); round[r].seedBalance = marketFund(); round[r].end = uint32(block.timestamp) + PREMARKET_LENGTH + RND_MAX; round[r].nextCb = CB_ONE; round[r].chadBroker = admin; emit NewRound(block.number); } function payBailouts(uint cb, uint pool) internal { Round storage _round = round[r]; address spender = _round.spender; address prod = _round.prod; address b1 = _round.lastBuys[(5 + _round.lastBuyIndex - 1) % 5]; address b2 = _round.lastBuys[(5 + _round.lastBuyIndex - 2) % 5]; address b3 = _round.lastBuys[(5 + _round.lastBuyIndex - 3) % 5]; address b4 = _round.lastBuys[(5 + _round.lastBuyIndex - 4) % 5]; address b5 = _round.lastBuys[(5 + _round.lastBuyIndex - 5) % 5]; // add the pool to divBal divBal += pool; uint a = pool / 1000; // production gets 10% uint sent = a * 100; player[prod].availableDivs += sent; player[prod].playerRound[r].bailoutDivs += sent; // each trade gets 4% uint buyerBailout = a * 40; player[b1].availableDivs += buyerBailout; player[b2].availableDivs += buyerBailout; player[b3].availableDivs += buyerBailout; player[b4].availableDivs += buyerBailout; player[b5].availableDivs += buyerBailout; player[b1].playerRound[r].bailoutDivs += buyerBailout; player[b2].playerRound[r].bailoutDivs += buyerBailout; player[b3].playerRound[r].bailoutDivs += buyerBailout; player[b4].playerRound[r].bailoutDivs += buyerBailout; player[b5].playerRound[r].bailoutDivs += buyerBailout; sent += buyerBailout * 5; // spender gets 70% + leftovers player[spender].availableDivs += (pool - sent); player[spender].playerRound[r].bailoutDivs += (pool - sent); BailoutEvent memory e; e.prod = addressToName[prod]; e.spender = addressToName[spender]; e.b1 = addressToName[b1]; e.b2 = addressToName[b2]; e.b3 = addressToName[b3]; e.b4 = addressToName[b4]; e.b5 = addressToName[b5]; e.round = r; e.cb = cb; e.amount = pool; emit LogBailouts(e); } function invest() external { if (block.timestamp > round[r].end) {// market crash incrementRound(); return; } if (round[r].stonkMarket > round[r].nextCb) { bool roundOver = handleCircuitBreaker(); if (roundOver) { return; } } address addr = msg.sender; uint stonks = getStonks(addr); require(stonks > 0, 'No stonks to invest'); uint value = calculateSell(stonks); uint companies = stonks / INVEST_RATIO; player[addr].playerRound[r].companies += companies; address prod = round[r].prod; if (getCompanies(addr) > getCompanies(prod)) { round[r].prod = addr; } // Reset counter player[addr].playerRound[r].lastAction = block.timestamp; player[addr].playerRound[r].oldRateStonks = 0; writeHistory(); emit LogInvest(addressToName[addr], value); } function withdrawBonus() public { address addr = msg.sender; uint amount = player[addr].availableDivs; divBal = divBal.sub(amount); uint divs = totalPreMarketDivs(addr).sub(player[addr].preMarketDivsWithdrawn); if (divs > 0) { pmDivBal = pmDivBal.sub(divs); amount += divs; player[addr].preMarketDivsWithdrawn += divs; } require(amount > 0); player[addr].availableDivs = 0; token.transfer(addr, amount); emit LogWithdraw(addressToName[addr], amount); } function writeHistory() internal { emit LogHistory(round[r].index++, marketFund(), round[r].stonkMarket, block.timestamp); } function calculatePreMarketOwned(address addr) internal view returns (uint) { if (player[addr].playerRound[r].preMarketSpent == 0) { return 0; } uint stonks = calculateTrade(round[r].preMarketSpent, round[r].seedBalance, MARKET_RESET); uint stonkFee = (stonks * FEE) / 100; stonks -= stonkFee; uint totalSpentBig = round[r].preMarketSpent * 100; // inflate for precision uint userPercent = stonks / (totalSpentBig / player[addr].playerRound[r].preMarketSpent); return (userPercent * 100) / INVEST_RATIO; } function feeSplit(uint amount) internal { uint a = amount / 20; // 1% Round storage _round = round[r]; if (block.timestamp < PREMARKET_LENGTH + _round.seedTime) { // pre-market open, don't pay PM divs or chad _round.bailoutFund += (amount - (a * 3)); // bailout fund gets 17% } else { // pre-market over if (_round.nextCb == CB_ONE) { // - - - cb1: _round.preMarketDivs += (a * 4); // 4% for pm divs pmDivBal += (a * 4); // 8 = pm (4) + devs (3) + chad (1) _round.bailoutFund += (amount - (a * 8)); // bailout fund gets 12% } else if (_round.nextCb == CB_TWO) { // - - - cb2: _round.preMarketDivs += (a * 7); // 7% for pm divs pmDivBal += (a * 7); // 11 = pm (7) + devs (3) + chad (1) _round.bailoutFund += (amount - (a * 11)); // bailout fund gets 9% } else { // - - - cb3: _round.preMarketDivs += (a * 15); // 15% for pm divs pmDivBal += (a * 15); // 19 = pm (15) + devs (3) + chad (1) _round.bailoutFund += (amount - (a * 19)); // bailout fund gets 1% } // chadbroker always gets 1% after premarket player[_round.chadBroker].playerRound[r].chadBrokerDivs += a; player[_round.chadBroker].availableDivs += a; divBal += a; } // devs always get 3% devBal += a * 3; } function stonkNumbers(address addr, uint buyAmount) public view returns (uint companies, uint stonks, uint receiveBuy, uint receiveSell, uint dividends) { companies = getCompanies(addr); if (companies > 0) { stonks = getStonks(addr); if (stonks > 0) { receiveSell = calculateSell(stonks); } } if (buyAmount > 0) { receiveBuy = calculateBuy(buyAmount) / INVEST_RATIO; } dividends = player[addr].availableDivs + totalPreMarketDivs(addr).sub(player[addr].preMarketDivsWithdrawn); } function updateLastBuyer() internal { round[r].lastBuys[round[r].lastBuyIndex] = msg.sender; round[r].lastBuyIndex = (round[r].lastBuyIndex + 1) % 5; } function updateChadBroker(address addr) internal { PlayerRound memory _brokerRound = player[addr].playerRound[r]; PlayerRound memory _chadBrokerRound = player[round[r].chadBroker].playerRound[r]; if ( (_brokerRound.brokerDivs > _chadBrokerRound.brokerDivs) && (_brokerRound.brokeredTrades > _chadBrokerRound.brokeredTrades) ) { round[r].chadBroker = addr; emit NewChad(addressToName[addr], _brokerRound.brokerDivs, _brokerRound.brokeredTrades); } } function incrementTimer(uint amount) internal { uint incr; if (round[r].stonkMarket < CB_ONE) { // CB1 = $48 per day incr = 30 minutes; } else if (round[r].stonkMarket < CB_TWO) { // CB2 = $144 per day incr = 10 minutes; } else { incr = 1 minutes; // CB3 = $1440 per day } uint newTime = round[r].end + uint32((amount / 1e6) * incr); if (newTime > block.timestamp + RND_MAX) { round[r].end = uint32(block.timestamp) + RND_MAX; } else { round[r].end = uint32(newTime); } } function leaderNumbers() public view returns (uint, uint, uint, uint, uint, uint, uint) { address spender = round[r].spender; address prod = round[r].prod; address chad = round[r].chadBroker; return ( player[spender].playerRound[r].spent, userRoundEarned(spender, r), getCompanies(prod), getStonks(prod), player[chad].playerRound[r].brokeredTrades, player[chad].playerRound[r].brokerDivs, player[chad].playerRound[r].chadBrokerDivs ); } function userRoundEarned(address addr, uint rnd) internal view returns (uint earned) { PlayerRound memory _playerRound = player[addr].playerRound[rnd]; earned += calculatePreMarketDivs(addr, rnd); earned += _playerRound.stonkDivs; earned += _playerRound.cashbackDivs; earned += _playerRound.brokerDivs; earned += _playerRound.bailoutDivs; earned += _playerRound.chadBrokerDivs; } function getCompanies(address addr) internal view returns (uint) { return (player[addr].playerRound[r].companies + calculatePreMarketOwned(addr)); } function marketFund() internal view returns (uint) { return token.balanceOf(address(this)) - (round[r].bailoutFund + divBal + pmDivBal + devBal); } function calculateTrade(uint rt, uint rs, uint bs) internal pure returns (uint) { return PSN.mul(bs) / PSNH.add(PSN.mul(rs).add(PSNH.mul(rt)) / rt); } function calculateSell(uint stonks) internal view returns (uint) { uint received = calculateTrade(stonks, round[r].stonkMarket, marketFund()); uint fee = (received * FEE) / 100; return (received - fee); } function calculateBuy(uint spent) internal view returns (uint) { uint stonks = calculateTrade(spent, marketFund(), round[r].stonkMarket); uint stonkFee = (stonks * FEE) / 100; return (stonks - stonkFee); } function getStonks(address addr) internal view returns (uint) { return player[addr].playerRound[r].oldRateStonks.add(currentRateStonks(addr)); } function currentRateStonks(address addr) internal view returns (uint) { if (player[addr].playerRound[r].lastAction > block.timestamp) {// applies during premarket return 0; } uint secondsPassed = block.timestamp - player[addr].playerRound[r].lastAction; return secondsPassed.mul(getCompanies(addr)); } function preStonkMarket(uint totalSpent) // determines stonkMarket value after premarket buys internal view returns (uint) { uint stonks = calculateTrade(totalSpent, round[r].seedBalance, MARKET_RESET); uint stonkFee = (stonks * FEE) / 100; return ((stonks - stonkFee) / 10) + MARKET_RESET; } function calculatePreMarketDivs(address addr, uint rnd) public view returns (uint) { if (player[addr].playerRound[rnd].preMarketSpent == 0) { return 0; } uint totalDivs = round[rnd].preMarketDivs; uint totalSpent = round[rnd].preMarketSpent; uint playerSpent = player[addr].playerRound[rnd].preMarketSpent; uint playerDivs = (((playerSpent * 2 ** 64) / totalSpent) * totalDivs) / 2 ** 64; return playerDivs; } function gameData() public view returns (uint rnd, uint index, uint open, uint end, uint fund, uint market, uint bailout) { return ( r, round[r].index, marketOpen(), round[r].end, marketFund(), round[r].stonkMarket, round[r].bailoutFund ); } function totalPreMarketDivs(address addr) internal view returns (uint) { uint divs; for (uint rnd = 1; rnd <= r; rnd++) { divs += calculatePreMarketDivs(addr, rnd); } return divs; } function marketOpen() internal view returns (uint) { if (block.timestamp > round[r].seedTime + PREMARKET_LENGTH) { return 0; } return (round[r].seedTime + PREMARKET_LENGTH) - block.timestamp; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"address","name":"_stonkRevenueService","type":"address"},{"internalType":"uint32","name":"_open","type":"uint32"},{"internalType":"contract EthStonksLibrary","name":"_lib","type":"address"},{"internalType":"address","name":"_priceFeed","type":"address"},{"internalType":"contract StonkNFT","name":"_nft","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"components":[{"internalType":"string","name":"prod","type":"string"},{"internalType":"string","name":"spender","type":"string"},{"internalType":"string","name":"b1","type":"string"},{"internalType":"string","name":"b2","type":"string"},{"internalType":"string","name":"b3","type":"string"},{"internalType":"string","name":"b4","type":"string"},{"internalType":"string","name":"b5","type":"string"},{"internalType":"uint256","name":"round","type":"uint256"},{"internalType":"uint256","name":"cb","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"indexed":false,"internalType":"struct EthStonks.BailoutEvent","name":"e","type":"tuple"}],"name":"LogBailouts","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"broker","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isBroker","type":"bool"},{"indexed":false,"internalType":"bool","name":"validBroker","type":"bool"}],"name":"LogBuy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fund","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"market","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"LogHistory","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"LogInvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"broker","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isBroker","type":"bool"},{"indexed":false,"internalType":"bool","name":"validBroker","type":"bool"}],"name":"LogPreMarketBuy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"LogSell","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"LogWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NewBroker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"divs","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"trades","type":"uint256"}],"name":"NewChad","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NewPlayer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewRound","type":"event"},{"inputs":[],"name":"BROKER_REQ","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_BUY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_NFT_BUY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressToName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_broker","type":"string"}],"name":"buy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"rnd","type":"uint256"}],"name":"calculatePreMarketDivs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"checkName","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"claimBroker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devBal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"divBal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableGas","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_featuredBroker","type":"string"}],"name":"featureBroker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gameData","outputs":[{"internalType":"uint256","name":"rnd","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"open","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"uint256","name":"fund","type":"uint256"},{"internalType":"uint256","name":"market","type":"uint256"},{"internalType":"uint256","name":"bailout","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rnd","type":"uint256"},{"internalType":"uint256","name":"ind","type":"uint256"}],"name":"getAddrById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rnd","type":"uint256"},{"internalType":"address","name":"addr","type":"address"}],"name":"getIdByAddr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"rnd","type":"uint256"},{"internalType":"uint256","name":"key","type":"uint256"}],"name":"getPlayerMetric","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rnd","type":"uint256"}],"name":"getRoundIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rnd","type":"uint256"}],"name":"getRoundLastBuyIndex","outputs":[{"internalType":"int8","name":"","type":"int8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rnd","type":"uint256"},{"internalType":"uint256","name":"key","type":"uint256"}],"name":"getRoundMetric","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"grantBroker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"invest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rnd","type":"uint256"},{"internalType":"int8","name":"index","type":"int8"}],"name":"lastBuy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"leaderNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_str","type":"string"}],"name":"nameLength","outputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"nameToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pmDivBal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_broker","type":"string"}],"name":"preMarketBuy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"r","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"registerName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"registerNameAndClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"seedMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"val","type":"bool"}],"name":"setGasFlag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setStonkRevenueService","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"stonkNames","outputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_broker","type":"string"},{"internalType":"string","name":"_featuredBroker","type":"string"},{"internalType":"string","name":"_spender","type":"string"},{"internalType":"string","name":"_producer","type":"string"},{"internalType":"string","name":"_chad","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"buyAmount","type":"uint256"}],"name":"stonkNumbers","outputs":[{"internalType":"uint256","name":"companies","type":"uint256"},{"internalType":"uint256","name":"stonks","type":"uint256"},{"internalType":"uint256","name":"receiveBuy","type":"uint256"},{"internalType":"uint256","name":"receiveSell","type":"uint256"},{"internalType":"uint256","name":"dividends","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"toString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"toString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"toString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"rnd","type":"uint256"}],"name":"userRoundStats","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawBonus","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260016006556040518060400160405280600381526020017f4d72460000000000000000000000000000000000000000000000000000000000815250600a908051906020019062000056929190620005ef565b506001600e60146101000a81548160ff0219169083151502179055503480156200007f57600080fd5b506040516200662e3803806200662e8339818101604052810190620000a5919062000701565b6000600560006006548152602001908152602001600020905060008160010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415620001ff5780600c0160009054906101000a900463ffffffff1663ffffffff168160010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503381600001600083600c01600081819054906101000a900463ffffffff168092919060010191906101000a81548163ffffffff021916908363ffffffff16021790555063ffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b81600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555086600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060400160405280600381526020017f4d72460000000000000000000000000000000000000000000000000000000000815250600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190620003ee929190620005ef565b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660036040516200042090620007d9565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660056000600654815260200190815260200160002060080160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620151808503600560006006548152602001908152602001600020600c0160046101000a81548163ffffffff021916908363ffffffff16021790555064c92a69c000600560006006548152602001908152602001600020600501819055506203f4808501600560006006548152602001908152602001600020600c0160086101000a81548163ffffffff021916908363ffffffff160217905550662386f26fc10000600560006006548152602001908152602001600020600b018190555082600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050620008cf565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928262000627576000855562000673565b82601f106200064257805160ff191683800117855562000673565b8280016001018555821562000673579182015b828111156200067257825182559160200191906001019062000655565b5b50905062000682919062000686565b5090565b5b80821115620006a157600081600090555060010162000687565b5090565b600081519050620006b68162000867565b92915050565b600081519050620006cd8162000881565b92915050565b600081519050620006e4816200089b565b92915050565b600081519050620006fb81620008b5565b92915050565b60008060008060008060c087890312156200071b57600080fd5b60006200072b89828a01620006a5565b96505060206200073e89828a01620006a5565b95505060406200075189828a01620006ea565b94505060606200076489828a01620006bc565b93505060806200077789828a01620006a5565b92505060a06200078a89828a01620006d3565b9150509295509295509295565b6000620007a6600383620007f0565b91507f4d724600000000000000000000000000000000000000000000000000000000006000830152600382019050919050565b6000620007e68262000797565b9150819050919050565b600081905092915050565b6000620008088262000837565b9050919050565b60006200081c82620007fb565b9050919050565b60006200083082620007fb565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600063ffffffff82169050919050565b6200087281620007fb565b81146200087e57600080fd5b50565b6200088c816200080f565b81146200089857600080fd5b50565b620008a68162000823565b8114620008b257600080fd5b50565b620008c08162000857565b8114620008cc57600080fd5b50565b615d4f80620008df6000396000f3fe608060405234801561001057600080fd5b506004361061025e5760003560e01c80636c8ae38c11610146578063c5051104116100c3578063e2a04b6211610087578063e2a04b6214610766578063e8b5e51f14610796578063f26a190f146107a0578063f3f54490146107bc578063fa0a80d6146107f0578063fa24f743146108285761025e565b8063c5051104146106ab578063d26a18ce146106e0578063d7a52259146106fc578063d85825331461072c578063db9bcc48146107485761025e565b806393b7586e1161010a57806393b7586e1461061b578063a0b3c3af1461064b578063a9e5539714610667578063ad606c7214610685578063b7dc3b181461068f5761025e565b80636c8ae38c1461056357806371aad10d1461058157806380aaddee146105b157806380ab66f3146105cd578063895265d1146105fd5761025e565b806345710074116101df57806356ca623e116101a357806356ca623e1461048f57806356eac451146104bf5780636122a0eb146104dd57806366de84ec146104f95780636900a3ae146105035780636c7f9527146105335761025e565b806345710074146103eb57806348ada1de146103f557806349b8c7581461041157806351010c7f14610441578063540bdfa31461045f5761025e565b80632ffb2a43116102265780632ffb2a431461033f57806333795ac3146103635780633af96b90146103815780633b6537551461039f5780633b66640b146103bb5761025e565b80630830602b1461026357806308d88aad1461027f5780631400d1e4146102af57806323044877146102df5780632f6aabc51461030f575b600080fd5b61027d60048036038101906102789190614c1d565b61084c565b005b61029960048036038101906102949190614ce2565b610bb3565b6040516102a691906155cb565b60405180910390f35b6102c960048036038101906102c49190614c1d565b610bfc565b6040516102d6919061567c565b60405180910390f35b6102f960048036038101906102f49190614d75565b610d42565b6040516103069190615886565b60405180910390f35b61032960048036038101906103249190614d23565b610da0565b6040516103369190615886565b60405180910390f35b610347610dd2565b60405161035a9796959493929190615926565b60405180910390f35b61036b610f17565b6040516103789190615886565b60405180910390f35b610389610f1d565b6040516103969190615886565b60405180910390f35b6103b960048036038101906103b49190614d23565b610f24565b005b6103d560048036038101906103d09190614e45565b61132f565b6040516103e291906155cb565b60405180910390f35b6103f3611381565b005b61040f600480360381019061040a9190614aff565b6115d5565b005b61042b60048036038101906104269190614db1565b611700565b60405161043891906155cb565b60405180910390f35b610449611758565b604051610456919061567c565b60405180910390f35b61047960048036038101906104749190614b28565b61176b565b6040516104869190615886565b60405180910390f35b6104a960048036038101906104a49190614aff565b6118a0565b6040516104b691906156f7565b60405180910390f35b6104c76118d1565b6040516104d49190615886565b60405180910390f35b6104f760048036038101906104f2919061500d565b6118d9565b005b610501611be5565b005b61051d60048036038101906105189190614d23565b611d2e565b60405161052a91906156f7565b60405180910390f35b61054d60048036038101906105489190614d23565b611d5f565b60405161055a91906156dc565b60405180910390f35b61056b611d8c565b6040516105789190615886565b60405180910390f35b61059b60048036038101906105969190614bdc565b611d92565b6040516105a891906156f7565b60405180910390f35b6105cb60048036038101906105c69190614ded565b612016565b005b6105e760048036038101906105e29190614b64565b61259b565b6040516105f49190615886565b60405180910390f35b610605612b93565b6040516106129190615886565b60405180910390f35b61063560048036038101906106309190614ce2565b612b9b565b6040516106429190615886565b60405180910390f35b61066560048036038101906106609190614aff565b612d27565b005b61066f612dc3565b60405161067c9190615886565b60405180910390f35b61068d612dc9565b005b6106a960048036038101906106a49190614ded565b612f9c565b005b6106c560048036038101906106c09190614aff565b613521565b6040516106d796959493929190615719565b60405180910390f35b6106fa60048036038101906106f59190614c62565b613c19565b005b61071660048036038101906107119190614e45565b613c35565b6040516107239190615886565b60405180910390f35b61074660048036038101906107419190614bb3565b613e1b565b005b610750613e90565b60405161075d9190615886565b60405180910390f35b610780600480360381019061077b9190614aff565b613e96565b60405161078d91906156f7565b60405180910390f35b61079e613f46565b005b6107ba60048036038101906107b59190614c1d565b61419a565b005b6107d660048036038101906107d19190614b28565b614208565b6040516107e79594939291906158d3565b60405180910390f35b61080a60048036038101906108059190614b28565b614354565b60405161081f99989796959493929190615995565b60405180910390f35b610830614492565b6040516108439796959493929190615926565b60405180910390f35b6000600560006006548152602001908152602001600020905060008160010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156109a55780600c0160009054906101000a900463ffffffff1663ffffffff168160010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503381600001600083600c01600081819054906101000a900463ffffffff168092919060010191906101000a81548163ffffffff021916908363ffffffff16021790555063ffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006109f582612b9b565b9050600c811115610a0557600080fd5b6003811015610a1357600080fd5b610a1c826145d7565b610a2557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff1660038686604051610a4f929190615520565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a9e57600080fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546001816001161561010002031660029004905014610afe57600080fd5b8484600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209190610b4c92919061487d565b503360038686604051610b60929190615520565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6003818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080610c4c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612b9b565b90506003811080610c5d5750600c81115b15610c6c576000915050610d3c565b610cb984848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506145d7565b15610d3657600073ffffffffffffffffffffffffffffffffffffffff1660038585604051610ce8929190615520565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614915050610d3c565b60009150505b92915050565b60006005600084815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600060056000838152602001908152602001600020600c01600c9054906101000a900461ffff1661ffff169050919050565b600080600080600080600080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f2ffb2a43000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610ea791906154e1565b600060405180830381855af49150503d8060008114610ee2576040519150601f19603f3d011682016040523d82523d6000602084013e610ee7565b606091505b5091505080806020019051810190610eff9190614ef8565b97509750975097509750975097505090919293949596565b60085481565b620f424081565b80620f4240811015610f6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6290615866565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401610fc9929190615601565b60206040518083038186803b158015610fe157600080fd5b505afa158015610ff5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110199190614d4c565b101561105a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105190615806565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016110b691906155e6565b60206040518083038186803b1580156110ce57600080fd5b505afa1580156110e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111069190614d4c565b1015611147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113e90615826565b60405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461119f57600080fd5b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff164210611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120b906157e6565b60405180910390fd5b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260405160240161125e9190615886565b6040516020818303038152906040527f3b653755000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516112e891906154e1565b600060405180830381855af49150503d8060008114611323576040519150601f19603f3d011682016040523d82523d6000602084013e611328565b606091505b5050505050565b600060056000848152602001908152602001600020600001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff1642116113f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ed906157c6565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900490501161148c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161148390615846565b60405180910390fd5b6000600e60149054906101000a900460ff16156114a7575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f45710074000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161157091906154e1565b600060405180830381855af49150503d80600081146115ab576040519150601f19603f3d011682016040523d82523d6000602084013e6115b0565b606091505b505050600e60149054906101000a900460ff16156115d2576115d18161474f565b5b50565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461162d57600080fd5b6001600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055507f2c27af2ff930faa587cc7012f6c34b11fc213dbd1bcc3e655a8a0734d2c4956d600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040516116f591906157a4565b60405180910390a150565b60006005600084815260200190815260200160002060090160008360000b60000b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b600e60149054906101000a900460ff1681565b600080600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160008481526020019081526020016000206000015414156117d4576000905061189a565b6000600560008481526020019081526020016000206004015490506000600560008581526020019081526020016000206003015490506000600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600401600086815260200190815260200160002060000154905060006801000000000000000084846801000000000000000085028161188657fe5b04028161188f57fe5b049050809450505050505b92915050565b60606118ca826040516020016118b691906154c6565b604051602081830303815290604052611d92565b9050919050565b6305f5e10081565b600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161561193357600080fd5b60006040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000469050600061197d336118a0565b61198683611d2e565b604051602001611997929190615550565b60405160208183030381529060405290506000816040516020016119bb9190615539565b604051602081830303815290604052805190602001209050600084826040516020016119e89291906154f8565b604051602081830303815290604052905060008180519060200120905060006001828b8b8b60405160008152602001604052604051611a2a9493929190615697565b6020604051602081039080840390855afa158015611a4c573d6000803e3d6000fd5b50505060206040510351905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161481604051602001611ab8919061558a565b60405160208183030381529060405290611b08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aff91906156f7565b60405180910390fd5b506001600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055507f2c27af2ff930faa587cc7012f6c34b11fc213dbd1bcc3e655a8a0734d2c4956d600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051611bd191906157a4565b60405180910390a150505050505050505050565b6000600e60149054906101000a900460ff1615611c00575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f66de84ec000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611cc991906154e1565b600060405180830381855af49150503d8060008114611d04576040519150601f19603f3d011682016040523d82523d6000602084013e611d09565b606091505b505050600e60149054906101000a900460ff1615611d2b57611d2a8161474f565b5b50565b6060611d5882604051602001611d4491906155b0565b604051602081830303815290604052611d92565b9050919050565b600060056000838152602001908152602001600020600c01600e9054906101000a900460000b9050919050565b60065481565b606060006040518060400160405280601081526020017f303132333435363738396162636465660000000000000000000000000000000081525090506000600284510260020167ffffffffffffffff81118015611dee57600080fd5b506040519080825280601f01601f191660200182016040528015611e215781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611e5257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611eaf57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060005b845181101561200b57826004868381518110611ef957fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff1681518110611f3857fe5b602001015160f81c60f81b826002830260020181518110611f5557fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535082600f60f81b868381518110611f9657fe5b602001015160f81c60f81b1660f81c60ff1681518110611fb257fe5b602001015160f81c60f81b826002830260030181518110611fcf57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080600101915050611ee1565b508092505050919050565b82620f424081101561205d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205490615866565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b81526004016120bb929190615601565b60206040518083038186803b1580156120d357600080fd5b505afa1580156120e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210b9190614d4c565b101561214c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214390615806565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016121a891906155e6565b60206040518083038186803b1580156121c057600080fd5b505afa1580156121d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f89190614d4c565b1015612239576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223090615826565b60405180910390fd5b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff1642106122ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a5906157e6565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546001816001161561010002031660029004905011612344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161233b90615846565b60405180910390fd5b6000600e60149054906101000a900460ff161561235f575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168585856040516024016123ad939291906158a1565b6040516020818303038152906040527f80aaddee000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161243791906154e1565b600060405180830381855af49150503d8060008114612472576040519150601f19603f3d011682016040523d82523d6000602084013e612477565b606091505b50505060016006541415612575576305f5e100851061257457600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166343a347cf33600560006001815260200190815260200160002060010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518363ffffffff1660e01b815260040161254192919061562a565b600060405180830381600087803b15801561255b57600080fd5b505af115801561256f573d6000803e3d6000fd5b505050505b5b600e60149054906101000a900460ff1615612594576125938161474f565b5b5050505050565b60008082141561260357600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600001549050612b8c565b600182141561266a57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600101549050612b8c565b60028214156126d157600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600201549050612b8c565b600382141561273857600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600301549050612b8c565b600482141561279f57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600401549050612b8c565b600582141561280657600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600501549050612b8c565b600682141561286d57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600601549050612b8c565b60078214156128d457600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600701549050612b8c565b600882141561293b57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600801549050612b8c565b60098214156129a257600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600901549050612b8c565b600a821415612a0957600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600a01549050612b8c565b600b821415612a5c57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050612b8c565b600c821415612aaf57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050612b8c565b600d821415612b1657600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600b01549050612b8c565b600e821415612b8757600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16612b7a576000612b7d565b60015b60ff169050612b8c565b600090505b9392505050565b633b9aca0081565b6000806000905060008390505b8051821015612d205760006007828481518110612bc157fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff161415612c0757600182019150612d13565b60066005828481518110612c1757fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff161415612c5d57600282019150612d12565b600e6004828481518110612c6d57fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff161415612cb357600382019150612d11565b601e6003828481518110612cc357fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff161415612d0957600482019150612d10565b6001820191505b5b5b5b8280600101935050612ba8565b5050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612d7f57600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60075481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e2157600080fd5b600060095411612e3057600080fd5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166009546040518363ffffffff1660e01b8152600401612eb1929190615653565b600060405180830381600087803b158015612ecb57600080fd5b505af1158015612edf573d6000803e3d6000fd5b505050506000600981905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166351cff8d9600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401612f6891906155cb565b600060405180830381600087803b158015612f8257600080fd5b505af1158015612f96573d6000803e3d6000fd5b50505050565b82620f4240811015612fe3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fda90615866565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401613041929190615601565b60206040518083038186803b15801561305957600080fd5b505afa15801561306d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130919190614d4c565b10156130d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130c990615806565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b815260040161312e91906155e6565b60206040518083038186803b15801561314657600080fd5b505afa15801561315a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317e9190614d4c565b10156131bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131b690615826565b60405180910390fd5b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff164211613234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161322b906157c6565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290049050116132ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132c190615846565b60405180910390fd5b6000600e60149054906101000a900460ff16156132e5575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16858585604051602401613333939291906158a1565b6040516020818303038152906040527fb7dc3b18000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516133bd91906154e1565b600060405180830381855af49150503d80600081146133f8576040519150601f19603f3d011682016040523d82523d6000602084013e6133fd565b606091505b505050600160065414156134fb576305f5e10085106134fa57600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1933600560006001815260200190815260200160002060010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518363ffffffff1660e01b81526004016134c792919061562a565b600060405180830381600087803b1580156134e157600080fd5b505af11580156134f5573d6000803e3d6000fd5b505050505b5b600e60149054906101000a900460ff161561351a576135198161474f565b5b5050505050565b606080606080606080600060056000600654815260200190815260200160002060060160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600060056000600654815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600060056000600654815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506060600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161561371757600260008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561370b5780601f106136e05761010080835404028352916020019161370b565b820191906000526020600020905b8154815290600101906020018083116136ee57829003601f168201915b505050505090506137f5565b600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156137ed5780601f106137c2576101008083540402835291602001916137ed565b820191906000526020600020905b8154815290600101906020018083116137d057829003601f168201915b505050505090505b600260008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081600a600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020858054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156139895780601f1061395e57610100808354040283529160200191613989565b820191906000526020600020905b81548152906001019060200180831161396c57829003601f168201915b50505050509550838054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613a255780601f106139fa57610100808354040283529160200191613a25565b820191906000526020600020905b815481529060010190602001808311613a0857829003601f168201915b50505050509350828054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613ac15780601f10613a9657610100808354040283529160200191613ac1565b820191906000526020600020905b815481529060010190602001808311613aa457829003601f168201915b50505050509250818054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613b5d5780601f10613b3257610100808354040283529160200191613b5d565b820191906000526020600020905b815481529060010190602001808311613b4057829003601f168201915b50505050509150808054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613bf95780601f10613bce57610100808354040283529160200191613bf9565b820191906000526020600020905b815481529060010190602001808311613bdc57829003601f168201915b505050505090509950995099509950995099505050505091939550919395565b613c23858561084c565b613c2e8383836118d9565b5050505050565b600080821415613c735760056000848152602001908152602001600020600c0160009054906101000a900463ffffffff1663ffffffff169050613e15565b6001821415613cac5760056000848152602001908152602001600020600c01600c9054906101000a900461ffff1661ffff169050613e15565b6002821415613ce95760056000848152602001908152602001600020600c0160049054906101000a900463ffffffff1663ffffffff169050613e15565b6003821415613d105760056000848152602001908152602001600020600201549050613e15565b6004821415613d375760056000848152602001908152602001600020600301549050613e15565b6005821415613d5e5760056000848152602001908152602001600020600401549050613e15565b6006821415613d9b5760056000848152602001908152602001600020600c0160089054906101000a900463ffffffff1663ffffffff169050613e15565b6007821415613dc25760056000848152602001908152602001600020600501549050613e15565b6008821415613de95760056000848152602001908152602001600020600a01549050613e15565b6009821415613e105760056000848152602001908152602001600020600b01549050613e15565b600090505b92915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613e7357600080fd5b80600e60146101000a81548160ff02191690831515021790555050565b60095481565b60026020528060005260406000206000915090508054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613f3e5780601f10613f1357610100808354040283529160200191613f3e565b820191906000526020600020905b815481529060010190602001808311613f2157829003601f168201915b505050505081565b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff164211613fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fb2906157c6565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546001816001161561010002031660029004905011614051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161404890615846565b60405180910390fd5b6000600e60149054906101000a900460ff161561406c575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527fe8b5e51f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161413591906154e1565b600060405180830381855af49150503d8060008114614170576040519150601f19603f3d011682016040523d82523d6000602084013e614175565b606091505b505050600e60149054906101000a900460ff1615614197576141968161474f565b5b50565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146141f257600080fd5b8181600a919061420392919061487d565b505050565b600080600080600080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16888860405160240161425d929190615653565b6040516020818303038152906040527ff3f54490000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516142e791906154e1565b600060405180830381855af49150503d8060008114614322576040519150601f19603f3d011682016040523d82523d6000602084013e614327565b606091505b509150508080602001905181019061433f9190614e81565b95509550955095509550509295509295909350565b600080600080600080600080600080600460008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160008c81526020019081526020016000206040518061018001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b820154815250509050806080015161444b8d8d61176b565b8260a001518360c001518460e00151856101000151866101200151876101400151886101600151995099509950995099509950995099509950509295985092959850929598565b600080600080600080600080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527ffa24f743000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161456791906154e1565b600060405180830381855af49150503d80600081146145a2576040519150601f19603f3d011682016040523d82523d6000602084013e6145a7565b606091505b50915050808060200190518101906145bf9190614ef8565b97509750975097509750975097505090919293949596565b6000805b82518110156147445760008382815181106145f257fe5b602001015160f81c60f81b9050603060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161015801561465b5750603960f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b1580156146c15750604160f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156146bf5750605a60f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b155b80156147265750606160f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156147245750607a60f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b155b156147365760009250505061474a565b5080806001019150506145db565b50600190505b919050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156147b957600080fd5b505afa1580156147cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147f19190614f96565b50505091505068056bc75e2d63100000813a61e2905a86030102028161481357fe5b04600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160006006548152602001908152602001600020600b01600082825401925050819055505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826148b357600085556148fa565b82601f106148cc57803560ff19168380011785556148fa565b828001600101855582156148fa579182015b828111156148f95782358255916020019190600101906148de565b5b509050614907919061490b565b5090565b5b8082111561492457600081600090555060010161490c565b5090565b600061493b61493684615a53565b615a22565b90508281526020810184848401111561495357600080fd5b61495e848285615bc7565b509392505050565b600061497961497484615a83565b615a22565b90508281526020810184848401111561499157600080fd5b61499c848285615bc7565b509392505050565b6000813590506149b381615c61565b92915050565b6000813590506149c881615c78565b92915050565b6000813590506149dd81615c8f565b92915050565b600082601f8301126149f457600080fd5b8135614a04848260208601614928565b91505092915050565b600081519050614a1c81615ca6565b92915050565b600081359050614a3181615cbd565b92915050565b60008083601f840112614a4957600080fd5b8235905067ffffffffffffffff811115614a6257600080fd5b602083019150836001820283011115614a7a57600080fd5b9250929050565b600082601f830112614a9257600080fd5b8135614aa2848260208601614966565b91505092915050565b600081359050614aba81615cd4565b92915050565b600081519050614acf81615cd4565b92915050565b600081359050614ae481615ceb565b92915050565b600081519050614af981615d02565b92915050565b600060208284031215614b1157600080fd5b6000614b1f848285016149a4565b91505092915050565b60008060408385031215614b3b57600080fd5b6000614b49858286016149a4565b9250506020614b5a85828601614aab565b9150509250929050565b600080600060608486031215614b7957600080fd5b6000614b87868287016149a4565b9350506020614b9886828701614aab565b9250506040614ba986828701614aab565b9150509250925092565b600060208284031215614bc557600080fd5b6000614bd3848285016149b9565b91505092915050565b600060208284031215614bee57600080fd5b600082013567ffffffffffffffff811115614c0857600080fd5b614c14848285016149e3565b91505092915050565b60008060208385031215614c3057600080fd5b600083013567ffffffffffffffff811115614c4a57600080fd5b614c5685828601614a37565b92509250509250929050565b600080600080600060808688031215614c7a57600080fd5b600086013567ffffffffffffffff811115614c9457600080fd5b614ca088828901614a37565b95509550506020614cb388828901614ad5565b9350506040614cc4888289016149ce565b9250506060614cd5888289016149ce565b9150509295509295909350565b600060208284031215614cf457600080fd5b600082013567ffffffffffffffff811115614d0e57600080fd5b614d1a84828501614a81565b91505092915050565b600060208284031215614d3557600080fd5b6000614d4384828501614aab565b91505092915050565b600060208284031215614d5e57600080fd5b6000614d6c84828501614ac0565b91505092915050565b60008060408385031215614d8857600080fd5b6000614d9685828601614aab565b9250506020614da7858286016149a4565b9150509250929050565b60008060408385031215614dc457600080fd5b6000614dd285828601614aab565b9250506020614de385828601614a22565b9150509250929050565b600080600060408486031215614e0257600080fd5b6000614e1086828701614aab565b935050602084013567ffffffffffffffff811115614e2d57600080fd5b614e3986828701614a37565b92509250509250925092565b60008060408385031215614e5857600080fd5b6000614e6685828601614aab565b9250506020614e7785828601614aab565b9150509250929050565b600080600080600060a08688031215614e9957600080fd5b6000614ea788828901614ac0565b9550506020614eb888828901614ac0565b9450506040614ec988828901614ac0565b9350506060614eda88828901614ac0565b9250506080614eeb88828901614ac0565b9150509295509295909350565b600080600080600080600060e0888a031215614f1357600080fd5b6000614f218a828b01614ac0565b9750506020614f328a828b01614ac0565b9650506040614f438a828b01614ac0565b9550506060614f548a828b01614ac0565b9450506080614f658a828b01614ac0565b93505060a0614f768a828b01614ac0565b92505060c0614f878a828b01614ac0565b91505092959891949750929550565b600080600080600060a08688031215614fae57600080fd5b6000614fbc88828901614aea565b9550506020614fcd88828901614a0d565b9450506040614fde88828901614ac0565b9350506060614fef88828901614ac0565b925050608061500088828901614aea565b9150509295509295909350565b60008060006060848603121561502257600080fd5b600061503086828701614ad5565b9350506020615041868287016149ce565b9250506040615052868287016149ce565b9150509250925092565b61506581615b91565b82525050565b61507481615b05565b82525050565b61508b61508682615b05565b615c09565b82525050565b61509a81615b17565b82525050565b6150a981615b23565b82525050565b6150c06150bb82615b23565b615c1b565b82525050565b60006150d182615ac8565b6150db8185615ade565b93506150eb818560208601615bd6565b80840191505092915050565b61510081615b37565b82525050565b60006151128385615ae9565b935061511f838584615bc7565b61512883615c43565b840190509392505050565b600061513f8385615afa565b935061514c838584615bc7565b82840190509392505050565b600061516382615ad3565b61516d8185615ae9565b935061517d818560208601615bd6565b61518681615c43565b840191505092915050565b600061519c82615ad3565b6151a68185615afa565b93506151b6818560208601615bd6565b80840191505092915050565b6000815460018116600081146151df576001811461520557615249565b607f60028304166151f08187615ae9565b955060ff198316865260208601935050615249565b600282046152138187615ae9565b955061521e85615ab3565b60005b8281101561524057815481890152600182019150602081019050615221565b80880195505050505b505092915050565b600061525e600e83615ae9565b91507f7072656d61726b6574206f70656e0000000000000000000000000000000000006000830152602082019050919050565b600061529e601083615ae9565b91507f7072656d61726b657420636c6f736564000000000000000000000000000000006000830152602082019050919050565b60006152de601583615afa565b91507f4772616e742073746f6e6b62726f6b657220746f2000000000000000000000006000830152601582019050919050565b600061531e600c83615ae9565b91507f6e6f20616c6c6f77616e636500000000000000000000000000000000000000006000830152602082019050919050565b600061535e600883615ae9565b91507f6e6f2066756e64730000000000000000000000000000000000000000000000006000830152602082019050919050565b600061539e600783615ae9565b91507f6e6f206e616d65000000000000000000000000000000000000000000000000006000830152602082019050919050565b60006153de601683615afa565b91507f5265636f766572656420616464726573732077617320000000000000000000006000830152601682019050919050565b600061541e600a83615afa565b91507f206f6e20636861696e20000000000000000000000000000000000000000000006000830152600a82019050919050565b600061545e600783615ae9565b91507f6d696e20627579000000000000000000000000000000000000000000000000006000830152602082019050919050565b61549a81615b64565b82525050565b6154b16154ac82615b64565b615c37565b82525050565b6154c081615b6e565b82525050565b60006154d2828461507a565b60148201915081905092915050565b60006154ed82846150c6565b915081905092915050565b600061550482856150c6565b915061551082846150af565b6020820191508190509392505050565b600061552d828486615133565b91508190509392505050565b60006155458284615191565b915081905092915050565b600061555b826152d1565b91506155678285615191565b915061557282615411565b915061557e8284615191565b91508190509392505050565b6000615595826153d1565b91506155a1828461507a565b60148201915081905092915050565b60006155bc82846154a0565b60208201915081905092915050565b60006020820190506155e0600083018461506b565b92915050565b60006020820190506155fb600083018461505c565b92915050565b6000604082019050615616600083018561505c565b615623602083018461506b565b9392505050565b600060408201905061563f600083018561505c565b61564c6020830184615491565b9392505050565b6000604082019050615668600083018561506b565b6156756020830184615491565b9392505050565b60006020820190506156916000830184615091565b92915050565b60006080820190506156ac60008301876150a0565b6156b960208301866154b7565b6156c660408301856150a0565b6156d360608301846150a0565b95945050505050565b60006020820190506156f160008301846150f7565b92915050565b600060208201905081810360008301526157118184615158565b905092915050565b600060c08201905081810360008301526157338189615158565b905081810360208301526157478188615158565b9050818103604083015261575b8187615158565b9050818103606083015261576f8186615158565b905081810360808301526157838185615158565b905081810360a08301526157978184615158565b9050979650505050505050565b600060208201905081810360008301526157be81846151c2565b905092915050565b600060208201905081810360008301526157df81615251565b9050919050565b600060208201905081810360008301526157ff81615291565b9050919050565b6000602082019050818103600083015261581f81615311565b9050919050565b6000602082019050818103600083015261583f81615351565b9050919050565b6000602082019050818103600083015261585f81615391565b9050919050565b6000602082019050818103600083015261587f81615451565b9050919050565b600060208201905061589b6000830184615491565b92915050565b60006040820190506158b66000830186615491565b81810360208301526158c9818486615106565b9050949350505050565b600060a0820190506158e86000830188615491565b6158f56020830187615491565b6159026040830186615491565b61590f6060830185615491565b61591c6080830184615491565b9695505050505050565b600060e08201905061593b600083018a615491565b6159486020830189615491565b6159556040830188615491565b6159626060830187615491565b61596f6080830186615491565b61597c60a0830185615491565b61598960c0830184615491565b98975050505050505050565b6000610120820190506159ab600083018c615491565b6159b8602083018b615491565b6159c5604083018a615491565b6159d26060830189615491565b6159df6080830188615491565b6159ec60a0830187615491565b6159f960c0830186615491565b615a0660e0830185615491565b615a14610100830184615491565b9a9950505050505050505050565b6000604051905081810181811067ffffffffffffffff82111715615a4957615a48615c41565b5b8060405250919050565b600067ffffffffffffffff821115615a6e57615a6d615c41565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115615a9e57615a9d615c41565b5b601f19601f8301169050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000615b1082615b44565b9050919050565b60008115159050919050565b6000819050919050565b6000819050919050565b60008160000b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600069ffffffffffffffffffff82169050919050565b6000615b9c82615ba3565b9050919050565b6000615bae82615bb5565b9050919050565b6000615bc082615b44565b9050919050565b82818337600083830152505050565b60005b83811015615bf4578082015181840152602081019050615bd9565b83811115615c03576000848401525b50505050565b6000615c1482615c25565b9050919050565b6000819050919050565b6000615c3082615c54565b9050919050565b6000819050919050565bfe5b6000601f19601f8301169050919050565b60008160601b9050919050565b615c6a81615b05565b8114615c7557600080fd5b50565b615c8181615b17565b8114615c8c57600080fd5b50565b615c9881615b23565b8114615ca357600080fd5b50565b615caf81615b2d565b8114615cba57600080fd5b50565b615cc681615b37565b8114615cd157600080fd5b50565b615cdd81615b64565b8114615ce857600080fd5b50565b615cf481615b6e565b8114615cff57600080fd5b50565b615d0b81615b7b565b8114615d1657600080fd5b5056fea2646970667358221220044bf06927f6b50e2252b0668d01ffd00ed540a0f37d6f872c22b18ef95a77e164736f6c63430007060033000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000137f4fa53577f08b6863ce92fc67433a9269ab95000000000000000000000000000000000000000000000000000000006061d6580000000000000000000000001cea5d3a73ca0a00453a4c9ffa03f61f92a23f170000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84190000000000000000000000000076b645920716be2ad8ecd41fdd6760bbb1124d
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061025e5760003560e01c80636c8ae38c11610146578063c5051104116100c3578063e2a04b6211610087578063e2a04b6214610766578063e8b5e51f14610796578063f26a190f146107a0578063f3f54490146107bc578063fa0a80d6146107f0578063fa24f743146108285761025e565b8063c5051104146106ab578063d26a18ce146106e0578063d7a52259146106fc578063d85825331461072c578063db9bcc48146107485761025e565b806393b7586e1161010a57806393b7586e1461061b578063a0b3c3af1461064b578063a9e5539714610667578063ad606c7214610685578063b7dc3b181461068f5761025e565b80636c8ae38c1461056357806371aad10d1461058157806380aaddee146105b157806380ab66f3146105cd578063895265d1146105fd5761025e565b806345710074116101df57806356ca623e116101a357806356ca623e1461048f57806356eac451146104bf5780636122a0eb146104dd57806366de84ec146104f95780636900a3ae146105035780636c7f9527146105335761025e565b806345710074146103eb57806348ada1de146103f557806349b8c7581461041157806351010c7f14610441578063540bdfa31461045f5761025e565b80632ffb2a43116102265780632ffb2a431461033f57806333795ac3146103635780633af96b90146103815780633b6537551461039f5780633b66640b146103bb5761025e565b80630830602b1461026357806308d88aad1461027f5780631400d1e4146102af57806323044877146102df5780632f6aabc51461030f575b600080fd5b61027d60048036038101906102789190614c1d565b61084c565b005b61029960048036038101906102949190614ce2565b610bb3565b6040516102a691906155cb565b60405180910390f35b6102c960048036038101906102c49190614c1d565b610bfc565b6040516102d6919061567c565b60405180910390f35b6102f960048036038101906102f49190614d75565b610d42565b6040516103069190615886565b60405180910390f35b61032960048036038101906103249190614d23565b610da0565b6040516103369190615886565b60405180910390f35b610347610dd2565b60405161035a9796959493929190615926565b60405180910390f35b61036b610f17565b6040516103789190615886565b60405180910390f35b610389610f1d565b6040516103969190615886565b60405180910390f35b6103b960048036038101906103b49190614d23565b610f24565b005b6103d560048036038101906103d09190614e45565b61132f565b6040516103e291906155cb565b60405180910390f35b6103f3611381565b005b61040f600480360381019061040a9190614aff565b6115d5565b005b61042b60048036038101906104269190614db1565b611700565b60405161043891906155cb565b60405180910390f35b610449611758565b604051610456919061567c565b60405180910390f35b61047960048036038101906104749190614b28565b61176b565b6040516104869190615886565b60405180910390f35b6104a960048036038101906104a49190614aff565b6118a0565b6040516104b691906156f7565b60405180910390f35b6104c76118d1565b6040516104d49190615886565b60405180910390f35b6104f760048036038101906104f2919061500d565b6118d9565b005b610501611be5565b005b61051d60048036038101906105189190614d23565b611d2e565b60405161052a91906156f7565b60405180910390f35b61054d60048036038101906105489190614d23565b611d5f565b60405161055a91906156dc565b60405180910390f35b61056b611d8c565b6040516105789190615886565b60405180910390f35b61059b60048036038101906105969190614bdc565b611d92565b6040516105a891906156f7565b60405180910390f35b6105cb60048036038101906105c69190614ded565b612016565b005b6105e760048036038101906105e29190614b64565b61259b565b6040516105f49190615886565b60405180910390f35b610605612b93565b6040516106129190615886565b60405180910390f35b61063560048036038101906106309190614ce2565b612b9b565b6040516106429190615886565b60405180910390f35b61066560048036038101906106609190614aff565b612d27565b005b61066f612dc3565b60405161067c9190615886565b60405180910390f35b61068d612dc9565b005b6106a960048036038101906106a49190614ded565b612f9c565b005b6106c560048036038101906106c09190614aff565b613521565b6040516106d796959493929190615719565b60405180910390f35b6106fa60048036038101906106f59190614c62565b613c19565b005b61071660048036038101906107119190614e45565b613c35565b6040516107239190615886565b60405180910390f35b61074660048036038101906107419190614bb3565b613e1b565b005b610750613e90565b60405161075d9190615886565b60405180910390f35b610780600480360381019061077b9190614aff565b613e96565b60405161078d91906156f7565b60405180910390f35b61079e613f46565b005b6107ba60048036038101906107b59190614c1d565b61419a565b005b6107d660048036038101906107d19190614b28565b614208565b6040516107e79594939291906158d3565b60405180910390f35b61080a60048036038101906108059190614b28565b614354565b60405161081f99989796959493929190615995565b60405180910390f35b610830614492565b6040516108439796959493929190615926565b60405180910390f35b6000600560006006548152602001908152602001600020905060008160010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414156109a55780600c0160009054906101000a900463ffffffff1663ffffffff168160010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503381600001600083600c01600081819054906101000a900463ffffffff168092919060010191906101000a81548163ffffffff021916908363ffffffff16021790555063ffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060006109f582612b9b565b9050600c811115610a0557600080fd5b6003811015610a1357600080fd5b610a1c826145d7565b610a2557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff1660038686604051610a4f929190615520565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a9e57600080fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546001816001161561010002031660029004905014610afe57600080fd5b8484600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209190610b4c92919061487d565b503360038686604051610b60929190615520565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6003818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080610c4c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612b9b565b90506003811080610c5d5750600c81115b15610c6c576000915050610d3c565b610cb984848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506145d7565b15610d3657600073ffffffffffffffffffffffffffffffffffffffff1660038585604051610ce8929190615520565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614915050610d3c565b60009150505b92915050565b60006005600084815260200190815260200160002060010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600060056000838152602001908152602001600020600c01600c9054906101000a900461ffff1661ffff169050919050565b600080600080600080600080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f2ffb2a43000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610ea791906154e1565b600060405180830381855af49150503d8060008114610ee2576040519150601f19603f3d011682016040523d82523d6000602084013e610ee7565b606091505b5091505080806020019051810190610eff9190614ef8565b97509750975097509750975097505090919293949596565b60085481565b620f424081565b80620f4240811015610f6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6290615866565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401610fc9929190615601565b60206040518083038186803b158015610fe157600080fd5b505afa158015610ff5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110199190614d4c565b101561105a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105190615806565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016110b691906155e6565b60206040518083038186803b1580156110ce57600080fd5b505afa1580156110e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111069190614d4c565b1015611147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113e90615826565b60405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461119f57600080fd5b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff164210611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120b906157e6565b60405180910390fd5b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260405160240161125e9190615886565b6040516020818303038152906040527f3b653755000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516112e891906154e1565b600060405180830381855af49150503d8060008114611323576040519150601f19603f3d011682016040523d82523d6000602084013e611328565b606091505b5050505050565b600060056000848152602001908152602001600020600001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff1642116113f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ed906157c6565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900490501161148c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161148390615846565b60405180910390fd5b6000600e60149054906101000a900460ff16156114a7575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f45710074000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161157091906154e1565b600060405180830381855af49150503d80600081146115ab576040519150601f19603f3d011682016040523d82523d6000602084013e6115b0565b606091505b505050600e60149054906101000a900460ff16156115d2576115d18161474f565b5b50565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461162d57600080fd5b6001600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055507f2c27af2ff930faa587cc7012f6c34b11fc213dbd1bcc3e655a8a0734d2c4956d600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040516116f591906157a4565b60405180910390a150565b60006005600084815260200190815260200160002060090160008360000b60000b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b600e60149054906101000a900460ff1681565b600080600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160008481526020019081526020016000206000015414156117d4576000905061189a565b6000600560008481526020019081526020016000206004015490506000600560008581526020019081526020016000206003015490506000600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600401600086815260200190815260200160002060000154905060006801000000000000000084846801000000000000000085028161188657fe5b04028161188f57fe5b049050809450505050505b92915050565b60606118ca826040516020016118b691906154c6565b604051602081830303815290604052611d92565b9050919050565b6305f5e10081565b600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161561193357600080fd5b60006040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525090506000469050600061197d336118a0565b61198683611d2e565b604051602001611997929190615550565b60405160208183030381529060405290506000816040516020016119bb9190615539565b604051602081830303815290604052805190602001209050600084826040516020016119e89291906154f8565b604051602081830303815290604052905060008180519060200120905060006001828b8b8b60405160008152602001604052604051611a2a9493929190615697565b6020604051602081039080840390855afa158015611a4c573d6000803e3d6000fd5b50505060206040510351905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161481604051602001611ab8919061558a565b60405160208183030381529060405290611b08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aff91906156f7565b60405180910390fd5b506001600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055507f2c27af2ff930faa587cc7012f6c34b11fc213dbd1bcc3e655a8a0734d2c4956d600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020604051611bd191906157a4565b60405180910390a150505050505050505050565b6000600e60149054906101000a900460ff1615611c00575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f66de84ec000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611cc991906154e1565b600060405180830381855af49150503d8060008114611d04576040519150601f19603f3d011682016040523d82523d6000602084013e611d09565b606091505b505050600e60149054906101000a900460ff1615611d2b57611d2a8161474f565b5b50565b6060611d5882604051602001611d4491906155b0565b604051602081830303815290604052611d92565b9050919050565b600060056000838152602001908152602001600020600c01600e9054906101000a900460000b9050919050565b60065481565b606060006040518060400160405280601081526020017f303132333435363738396162636465660000000000000000000000000000000081525090506000600284510260020167ffffffffffffffff81118015611dee57600080fd5b506040519080825280601f01601f191660200182016040528015611e215781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611e5257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611eaf57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060005b845181101561200b57826004868381518110611ef957fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff1681518110611f3857fe5b602001015160f81c60f81b826002830260020181518110611f5557fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535082600f60f81b868381518110611f9657fe5b602001015160f81c60f81b1660f81c60ff1681518110611fb257fe5b602001015160f81c60f81b826002830260030181518110611fcf57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080600101915050611ee1565b508092505050919050565b82620f424081101561205d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205490615866565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b81526004016120bb929190615601565b60206040518083038186803b1580156120d357600080fd5b505afa1580156120e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210b9190614d4c565b101561214c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214390615806565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016121a891906155e6565b60206040518083038186803b1580156121c057600080fd5b505afa1580156121d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f89190614d4c565b1015612239576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223090615826565b60405180910390fd5b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff1642106122ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a5906157e6565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546001816001161561010002031660029004905011612344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161233b90615846565b60405180910390fd5b6000600e60149054906101000a900460ff161561235f575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168585856040516024016123ad939291906158a1565b6040516020818303038152906040527f80aaddee000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161243791906154e1565b600060405180830381855af49150503d8060008114612472576040519150601f19603f3d011682016040523d82523d6000602084013e612477565b606091505b50505060016006541415612575576305f5e100851061257457600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166343a347cf33600560006001815260200190815260200160002060010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518363ffffffff1660e01b815260040161254192919061562a565b600060405180830381600087803b15801561255b57600080fd5b505af115801561256f573d6000803e3d6000fd5b505050505b5b600e60149054906101000a900460ff1615612594576125938161474f565b5b5050505050565b60008082141561260357600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600001549050612b8c565b600182141561266a57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600101549050612b8c565b60028214156126d157600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600201549050612b8c565b600382141561273857600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600301549050612b8c565b600482141561279f57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600401549050612b8c565b600582141561280657600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600501549050612b8c565b600682141561286d57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600601549050612b8c565b60078214156128d457600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600701549050612b8c565b600882141561293b57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600801549050612b8c565b60098214156129a257600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600901549050612b8c565b600a821415612a0957600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600a01549050612b8c565b600b821415612a5c57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050612b8c565b600c821415612aaf57600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050612b8c565b600d821415612b1657600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004016000848152602001908152602001600020600b01549050612b8c565b600e821415612b8757600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16612b7a576000612b7d565b60015b60ff169050612b8c565b600090505b9392505050565b633b9aca0081565b6000806000905060008390505b8051821015612d205760006007828481518110612bc157fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff161415612c0757600182019150612d13565b60066005828481518110612c1757fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff161415612c5d57600282019150612d12565b600e6004828481518110612c6d57fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff161415612cb357600382019150612d11565b601e6003828481518110612cc357fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff161415612d0957600482019150612d10565b6001820191505b5b5b5b8280600101935050612ba8565b5050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612d7f57600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60075481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e2157600080fd5b600060095411612e3057600080fd5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166009546040518363ffffffff1660e01b8152600401612eb1929190615653565b600060405180830381600087803b158015612ecb57600080fd5b505af1158015612edf573d6000803e3d6000fd5b505050506000600981905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166351cff8d9600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401612f6891906155cb565b600060405180830381600087803b158015612f8257600080fd5b505af1158015612f96573d6000803e3d6000fd5b50505050565b82620f4240811015612fe3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fda90615866565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401613041929190615601565b60206040518083038186803b15801561305957600080fd5b505afa15801561306d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130919190614d4c565b10156130d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130c990615806565b60405180910390fd5b80600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b815260040161312e91906155e6565b60206040518083038186803b15801561314657600080fd5b505afa15801561315a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317e9190614d4c565b10156131bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131b690615826565b60405180910390fd5b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff164211613234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161322b906157c6565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290049050116132ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132c190615846565b60405180910390fd5b6000600e60149054906101000a900460ff16156132e5575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16858585604051602401613333939291906158a1565b6040516020818303038152906040527fb7dc3b18000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516133bd91906154e1565b600060405180830381855af49150503d80600081146133f8576040519150601f19603f3d011682016040523d82523d6000602084013e6133fd565b606091505b505050600160065414156134fb576305f5e10085106134fa57600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1933600560006001815260200190815260200160002060010160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518363ffffffff1660e01b81526004016134c792919061562a565b600060405180830381600087803b1580156134e157600080fd5b505af11580156134f5573d6000803e3d6000fd5b505050505b5b600e60149054906101000a900460ff161561351a576135198161474f565b5b5050505050565b606080606080606080600060056000600654815260200190815260200160002060060160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600060056000600654815260200190815260200160002060070160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600060056000600654815260200190815260200160002060080160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506060600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161561371757600260008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561370b5780601f106136e05761010080835404028352916020019161370b565b820191906000526020600020905b8154815290600101906020018083116136ee57829003601f168201915b505050505090506137f5565b600460008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156137ed5780601f106137c2576101008083540402835291602001916137ed565b820191906000526020600020905b8154815290600101906020018083116137d057829003601f168201915b505050505090505b600260008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081600a600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020858054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156139895780601f1061395e57610100808354040283529160200191613989565b820191906000526020600020905b81548152906001019060200180831161396c57829003601f168201915b50505050509550838054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613a255780601f106139fa57610100808354040283529160200191613a25565b820191906000526020600020905b815481529060010190602001808311613a0857829003601f168201915b50505050509350828054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613ac15780601f10613a9657610100808354040283529160200191613ac1565b820191906000526020600020905b815481529060010190602001808311613aa457829003601f168201915b50505050509250818054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613b5d5780601f10613b3257610100808354040283529160200191613b5d565b820191906000526020600020905b815481529060010190602001808311613b4057829003601f168201915b50505050509150808054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613bf95780601f10613bce57610100808354040283529160200191613bf9565b820191906000526020600020905b815481529060010190602001808311613bdc57829003601f168201915b505050505090509950995099509950995099505050505091939550919395565b613c23858561084c565b613c2e8383836118d9565b5050505050565b600080821415613c735760056000848152602001908152602001600020600c0160009054906101000a900463ffffffff1663ffffffff169050613e15565b6001821415613cac5760056000848152602001908152602001600020600c01600c9054906101000a900461ffff1661ffff169050613e15565b6002821415613ce95760056000848152602001908152602001600020600c0160049054906101000a900463ffffffff1663ffffffff169050613e15565b6003821415613d105760056000848152602001908152602001600020600201549050613e15565b6004821415613d375760056000848152602001908152602001600020600301549050613e15565b6005821415613d5e5760056000848152602001908152602001600020600401549050613e15565b6006821415613d9b5760056000848152602001908152602001600020600c0160089054906101000a900463ffffffff1663ffffffff169050613e15565b6007821415613dc25760056000848152602001908152602001600020600501549050613e15565b6008821415613de95760056000848152602001908152602001600020600a01549050613e15565b6009821415613e105760056000848152602001908152602001600020600b01549050613e15565b600090505b92915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613e7357600080fd5b80600e60146101000a81548160ff02191690831515021790555050565b60095481565b60026020528060005260406000206000915090508054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613f3e5780601f10613f1357610100808354040283529160200191613f3e565b820191906000526020600020905b815481529060010190602001808311613f2157829003601f168201915b505050505081565b600560006006548152602001908152602001600020600c0160049054906101000a900463ffffffff16620151800163ffffffff164211613fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fb2906157c6565b60405180910390fd5b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546001816001161561010002031660029004905011614051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161404890615846565b60405180910390fd5b6000600e60149054906101000a900460ff161561406c575a90505b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527fe8b5e51f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161413591906154e1565b600060405180830381855af49150503d8060008114614170576040519150601f19603f3d011682016040523d82523d6000602084013e614175565b606091505b505050600e60149054906101000a900460ff1615614197576141968161474f565b5b50565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146141f257600080fd5b8181600a919061420392919061487d565b505050565b600080600080600080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16888860405160240161425d929190615653565b6040516020818303038152906040527ff3f54490000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516142e791906154e1565b600060405180830381855af49150503d8060008114614322576040519150601f19603f3d011682016040523d82523d6000602084013e614327565b606091505b509150508080602001905181019061433f9190614e81565b95509550955095509550509295509295909350565b600080600080600080600080600080600460008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160008c81526020019081526020016000206040518061018001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b820154815250509050806080015161444b8d8d61176b565b8260a001518360c001518460e00151856101000151866101200151876101400151886101600151995099509950995099509950995099509950509295985092959850929598565b600080600080600080600080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527ffa24f743000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161456791906154e1565b600060405180830381855af49150503d80600081146145a2576040519150601f19603f3d011682016040523d82523d6000602084013e6145a7565b606091505b50915050808060200190518101906145bf9190614ef8565b97509750975097509750975097505090919293949596565b6000805b82518110156147445760008382815181106145f257fe5b602001015160f81c60f81b9050603060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161015801561465b5750603960f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b1580156146c15750604160f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156146bf5750605a60f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b155b80156147265750606160f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156147245750607a60f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b155b156147365760009250505061474a565b5080806001019150506145db565b50600190505b919050565b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156147b957600080fd5b505afa1580156147cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147f19190614f96565b50505091505068056bc75e2d63100000813a61e2905a86030102028161481357fe5b04600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160006006548152602001908152602001600020600b01600082825401925050819055505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826148b357600085556148fa565b82601f106148cc57803560ff19168380011785556148fa565b828001600101855582156148fa579182015b828111156148f95782358255916020019190600101906148de565b5b509050614907919061490b565b5090565b5b8082111561492457600081600090555060010161490c565b5090565b600061493b61493684615a53565b615a22565b90508281526020810184848401111561495357600080fd5b61495e848285615bc7565b509392505050565b600061497961497484615a83565b615a22565b90508281526020810184848401111561499157600080fd5b61499c848285615bc7565b509392505050565b6000813590506149b381615c61565b92915050565b6000813590506149c881615c78565b92915050565b6000813590506149dd81615c8f565b92915050565b600082601f8301126149f457600080fd5b8135614a04848260208601614928565b91505092915050565b600081519050614a1c81615ca6565b92915050565b600081359050614a3181615cbd565b92915050565b60008083601f840112614a4957600080fd5b8235905067ffffffffffffffff811115614a6257600080fd5b602083019150836001820283011115614a7a57600080fd5b9250929050565b600082601f830112614a9257600080fd5b8135614aa2848260208601614966565b91505092915050565b600081359050614aba81615cd4565b92915050565b600081519050614acf81615cd4565b92915050565b600081359050614ae481615ceb565b92915050565b600081519050614af981615d02565b92915050565b600060208284031215614b1157600080fd5b6000614b1f848285016149a4565b91505092915050565b60008060408385031215614b3b57600080fd5b6000614b49858286016149a4565b9250506020614b5a85828601614aab565b9150509250929050565b600080600060608486031215614b7957600080fd5b6000614b87868287016149a4565b9350506020614b9886828701614aab565b9250506040614ba986828701614aab565b9150509250925092565b600060208284031215614bc557600080fd5b6000614bd3848285016149b9565b91505092915050565b600060208284031215614bee57600080fd5b600082013567ffffffffffffffff811115614c0857600080fd5b614c14848285016149e3565b91505092915050565b60008060208385031215614c3057600080fd5b600083013567ffffffffffffffff811115614c4a57600080fd5b614c5685828601614a37565b92509250509250929050565b600080600080600060808688031215614c7a57600080fd5b600086013567ffffffffffffffff811115614c9457600080fd5b614ca088828901614a37565b95509550506020614cb388828901614ad5565b9350506040614cc4888289016149ce565b9250506060614cd5888289016149ce565b9150509295509295909350565b600060208284031215614cf457600080fd5b600082013567ffffffffffffffff811115614d0e57600080fd5b614d1a84828501614a81565b91505092915050565b600060208284031215614d3557600080fd5b6000614d4384828501614aab565b91505092915050565b600060208284031215614d5e57600080fd5b6000614d6c84828501614ac0565b91505092915050565b60008060408385031215614d8857600080fd5b6000614d9685828601614aab565b9250506020614da7858286016149a4565b9150509250929050565b60008060408385031215614dc457600080fd5b6000614dd285828601614aab565b9250506020614de385828601614a22565b9150509250929050565b600080600060408486031215614e0257600080fd5b6000614e1086828701614aab565b935050602084013567ffffffffffffffff811115614e2d57600080fd5b614e3986828701614a37565b92509250509250925092565b60008060408385031215614e5857600080fd5b6000614e6685828601614aab565b9250506020614e7785828601614aab565b9150509250929050565b600080600080600060a08688031215614e9957600080fd5b6000614ea788828901614ac0565b9550506020614eb888828901614ac0565b9450506040614ec988828901614ac0565b9350506060614eda88828901614ac0565b9250506080614eeb88828901614ac0565b9150509295509295909350565b600080600080600080600060e0888a031215614f1357600080fd5b6000614f218a828b01614ac0565b9750506020614f328a828b01614ac0565b9650506040614f438a828b01614ac0565b9550506060614f548a828b01614ac0565b9450506080614f658a828b01614ac0565b93505060a0614f768a828b01614ac0565b92505060c0614f878a828b01614ac0565b91505092959891949750929550565b600080600080600060a08688031215614fae57600080fd5b6000614fbc88828901614aea565b9550506020614fcd88828901614a0d565b9450506040614fde88828901614ac0565b9350506060614fef88828901614ac0565b925050608061500088828901614aea565b9150509295509295909350565b60008060006060848603121561502257600080fd5b600061503086828701614ad5565b9350506020615041868287016149ce565b9250506040615052868287016149ce565b9150509250925092565b61506581615b91565b82525050565b61507481615b05565b82525050565b61508b61508682615b05565b615c09565b82525050565b61509a81615b17565b82525050565b6150a981615b23565b82525050565b6150c06150bb82615b23565b615c1b565b82525050565b60006150d182615ac8565b6150db8185615ade565b93506150eb818560208601615bd6565b80840191505092915050565b61510081615b37565b82525050565b60006151128385615ae9565b935061511f838584615bc7565b61512883615c43565b840190509392505050565b600061513f8385615afa565b935061514c838584615bc7565b82840190509392505050565b600061516382615ad3565b61516d8185615ae9565b935061517d818560208601615bd6565b61518681615c43565b840191505092915050565b600061519c82615ad3565b6151a68185615afa565b93506151b6818560208601615bd6565b80840191505092915050565b6000815460018116600081146151df576001811461520557615249565b607f60028304166151f08187615ae9565b955060ff198316865260208601935050615249565b600282046152138187615ae9565b955061521e85615ab3565b60005b8281101561524057815481890152600182019150602081019050615221565b80880195505050505b505092915050565b600061525e600e83615ae9565b91507f7072656d61726b6574206f70656e0000000000000000000000000000000000006000830152602082019050919050565b600061529e601083615ae9565b91507f7072656d61726b657420636c6f736564000000000000000000000000000000006000830152602082019050919050565b60006152de601583615afa565b91507f4772616e742073746f6e6b62726f6b657220746f2000000000000000000000006000830152601582019050919050565b600061531e600c83615ae9565b91507f6e6f20616c6c6f77616e636500000000000000000000000000000000000000006000830152602082019050919050565b600061535e600883615ae9565b91507f6e6f2066756e64730000000000000000000000000000000000000000000000006000830152602082019050919050565b600061539e600783615ae9565b91507f6e6f206e616d65000000000000000000000000000000000000000000000000006000830152602082019050919050565b60006153de601683615afa565b91507f5265636f766572656420616464726573732077617320000000000000000000006000830152601682019050919050565b600061541e600a83615afa565b91507f206f6e20636861696e20000000000000000000000000000000000000000000006000830152600a82019050919050565b600061545e600783615ae9565b91507f6d696e20627579000000000000000000000000000000000000000000000000006000830152602082019050919050565b61549a81615b64565b82525050565b6154b16154ac82615b64565b615c37565b82525050565b6154c081615b6e565b82525050565b60006154d2828461507a565b60148201915081905092915050565b60006154ed82846150c6565b915081905092915050565b600061550482856150c6565b915061551082846150af565b6020820191508190509392505050565b600061552d828486615133565b91508190509392505050565b60006155458284615191565b915081905092915050565b600061555b826152d1565b91506155678285615191565b915061557282615411565b915061557e8284615191565b91508190509392505050565b6000615595826153d1565b91506155a1828461507a565b60148201915081905092915050565b60006155bc82846154a0565b60208201915081905092915050565b60006020820190506155e0600083018461506b565b92915050565b60006020820190506155fb600083018461505c565b92915050565b6000604082019050615616600083018561505c565b615623602083018461506b565b9392505050565b600060408201905061563f600083018561505c565b61564c6020830184615491565b9392505050565b6000604082019050615668600083018561506b565b6156756020830184615491565b9392505050565b60006020820190506156916000830184615091565b92915050565b60006080820190506156ac60008301876150a0565b6156b960208301866154b7565b6156c660408301856150a0565b6156d360608301846150a0565b95945050505050565b60006020820190506156f160008301846150f7565b92915050565b600060208201905081810360008301526157118184615158565b905092915050565b600060c08201905081810360008301526157338189615158565b905081810360208301526157478188615158565b9050818103604083015261575b8187615158565b9050818103606083015261576f8186615158565b905081810360808301526157838185615158565b905081810360a08301526157978184615158565b9050979650505050505050565b600060208201905081810360008301526157be81846151c2565b905092915050565b600060208201905081810360008301526157df81615251565b9050919050565b600060208201905081810360008301526157ff81615291565b9050919050565b6000602082019050818103600083015261581f81615311565b9050919050565b6000602082019050818103600083015261583f81615351565b9050919050565b6000602082019050818103600083015261585f81615391565b9050919050565b6000602082019050818103600083015261587f81615451565b9050919050565b600060208201905061589b6000830184615491565b92915050565b60006040820190506158b66000830186615491565b81810360208301526158c9818486615106565b9050949350505050565b600060a0820190506158e86000830188615491565b6158f56020830187615491565b6159026040830186615491565b61590f6060830185615491565b61591c6080830184615491565b9695505050505050565b600060e08201905061593b600083018a615491565b6159486020830189615491565b6159556040830188615491565b6159626060830187615491565b61596f6080830186615491565b61597c60a0830185615491565b61598960c0830184615491565b98975050505050505050565b6000610120820190506159ab600083018c615491565b6159b8602083018b615491565b6159c5604083018a615491565b6159d26060830189615491565b6159df6080830188615491565b6159ec60a0830187615491565b6159f960c0830186615491565b615a0660e0830185615491565b615a14610100830184615491565b9a9950505050505050505050565b6000604051905081810181811067ffffffffffffffff82111715615a4957615a48615c41565b5b8060405250919050565b600067ffffffffffffffff821115615a6e57615a6d615c41565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115615a9e57615a9d615c41565b5b601f19601f8301169050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000615b1082615b44565b9050919050565b60008115159050919050565b6000819050919050565b6000819050919050565b60008160000b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600069ffffffffffffffffffff82169050919050565b6000615b9c82615ba3565b9050919050565b6000615bae82615bb5565b9050919050565b6000615bc082615b44565b9050919050565b82818337600083830152505050565b60005b83811015615bf4578082015181840152602081019050615bd9565b83811115615c03576000848401525b50505050565b6000615c1482615c25565b9050919050565b6000819050919050565b6000615c3082615c54565b9050919050565b6000819050919050565bfe5b6000601f19601f8301169050919050565b60008160601b9050919050565b615c6a81615b05565b8114615c7557600080fd5b50565b615c8181615b17565b8114615c8c57600080fd5b50565b615c9881615b23565b8114615ca357600080fd5b50565b615caf81615b2d565b8114615cba57600080fd5b50565b615cc681615b37565b8114615cd157600080fd5b50565b615cdd81615b64565b8114615ce857600080fd5b50565b615cf481615b6e565b8114615cff57600080fd5b50565b615d0b81615b7b565b8114615d1657600080fd5b5056fea2646970667358221220044bf06927f6b50e2252b0668d01ffd00ed540a0f37d6f872c22b18ef95a77e164736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000137f4fa53577f08b6863ce92fc67433a9269ab95000000000000000000000000000000000000000000000000000000006061d6580000000000000000000000001cea5d3a73ca0a00453a4c9ffa03f61f92a23f170000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84190000000000000000000000000076b645920716be2ad8ecd41fdd6760bbb1124d
-----Decoded View---------------
Arg [0] : _tokenAddress (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [1] : _stonkRevenueService (address): 0x137F4fa53577f08b6863Ce92fC67433A9269ab95
Arg [2] : _open (uint32): 1617024600
Arg [3] : _lib (address): 0x1cEa5D3a73ca0a00453a4c9fFa03F61f92A23f17
Arg [4] : _priceFeed (address): 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
Arg [5] : _nft (address): 0x0076b645920716Be2aD8ecD41fDd6760BbB1124d
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [1] : 000000000000000000000000137f4fa53577f08b6863ce92fc67433a9269ab95
Arg [2] : 000000000000000000000000000000000000000000000000000000006061d658
Arg [3] : 0000000000000000000000001cea5d3a73ca0a00453a4c9ffa03f61f92a23f17
Arg [4] : 0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419
Arg [5] : 0000000000000000000000000076b645920716be2ad8ecd41fdd6760bbb1124d
Deployed Bytecode Sourcemap
2523:20836:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20842:393;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6169:47;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20484:350;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14756:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14902:117;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16583:292;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;6433:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4598:34;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8515:212;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14612:136;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11502:163;;;:::i;:::-;;8735:162;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13328:138;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6784:28;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14095:509;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22567:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4688:40;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8905:1093;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;11673:147;;;:::i;:::-;;22722:143;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17773:133;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6318:17;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22873:483;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10444:446;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;15027:1548;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4639:40;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21918:641;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8276:125;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6344:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10155:256;;;:::i;:::-;;10898:421;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;11867:738;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;21243:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;16883:882;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8409:98;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6526:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6115:47;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11327:167;;;:::i;:::-;;10006:141;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;12613:376;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;13510:577;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;12997:323;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;20842:393;3611:20;3634:5;:8;3640:1;;3634:8;;;;;;;;;;;3611:31;;3688:1;3657:6;:15;;:27;3673:10;3657:27;;;;;;;;;;;;;;;;:32;3653:178;;;3736:6;:18;;;;;;;;;;;;3706:48;;:6;:15;;:27;3722:10;3706:27;;;;;;;;;;;;;;;:48;;;;3809:10;3769:6;:15;;:37;3785:6;:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3769:37;;;;;;;;;;;;;;:50;;;;;;;;;;;;;;;;;;3653:178;20936:4:::1;;3352:211;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3402:11;3416:16;3427:4;3416:10;:16::i;:::-;3402:30;;3461:2;3451:6;:12;;3443:21;;;::::0;::::1;;3493:1;3483:6;:11;;3475:20;;;::::0;::::1;;3514:28;3536:4;3514:15;:28::i;:::-;3506:37;;;::::0;::::1;;21036:1:::2;21005:33;;:13;21019:4;;21005:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;:33;;;20997:42;;;::::0;::::2;;21137:1;21100:13;:25;21114:10;21100:25;;;;;;;;;;;;;;;21094:39;;;;;;;;;;;;;;;;:44;21086:53;;;::::0;::::2;;21180:4;;21152:13;:25;21166:10;21152:25;;;;;;;;;;;;;;;:32;;;;;;;:::i;:::-;;21217:10;21195:13;21209:4;;21195:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;3841:1:::1;;20842:393:::0;;;:::o;6169:47::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;20484:350::-;20558:4;20580:11;20594:16;20605:4;;20594:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:10;:16::i;:::-;20580:30;;20634:1;20625:6;:10;:25;;;;20648:2;20639:6;:11;20625:25;20621:70;;;20674:5;20667:12;;;;;20621:70;20705:28;20727:4;;20705:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:15;:28::i;:::-;20701:103;;;20789:1;20758:33;;:13;20772:4;;20758:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;:33;;;20750:42;;;;;20701:103;20821:5;20814:12;;;20484:350;;;;;:::o;14756:138::-;14832:4;14861:5;:10;14867:3;14861:10;;;;;;;;;;;:19;;:25;14881:4;14861:25;;;;;;;;;;;;;;;;14854:32;;14756:138;;;;:::o;14902:117::-;14966:4;14995:5;:10;15001:3;14995:10;;;;;;;;;;;:16;;;;;;;;;;;;14988:23;;;;14902:117;;;:::o;16583:292::-;16634:4;16640;16646;16652;16658;16664;16670;16695:19;16726:3;;;;;;;;;;;16718:25;;16744:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16718:69;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16692:95;;;16816:6;16805:62;;;;;;;;;;;;:::i;:::-;16798:69;;;;;;;;;;;;;;;16583:292;;;;;;;:::o;6433:18::-;;;;:::o;4598:34::-;4629:3;4598:34;:::o;8515:212::-;8580:6;4629:3;3017:6;:17;;3009:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;3111:6;3065:5;;;;;;;;;;;:15;;;3081:10;3101:4;3065:42;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;3057:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;3184:6;3153:5;;;;;;;;;;;:15;;;3169:10;3153:27;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:37;;3145:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;2635:5:::1;::::0;::::1;;;;;;;;2621:19;;:10;:19;;;2613:28;;;::::0;::::1;;2750:5:::2;:8;2756:1;;2750:8;;;;;;;;;;;:17;;;;;;;;;;;;4543:8;2731:36;2713:54;;:15;:54;2705:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;8646:3:::3;;;;;;;;;;;8638:25;;8711:6;8664:54;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8638:81;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8515:212:::0;;:::o;14612:136::-;14684:7;14716:5;:10;14722:3;14716:10;;;;;;;;;;;:19;;:24;14736:3;14716:24;;;;;;;;;;;;;;;;;;;;;14709:31;;14612:136;;;;:::o;11502:163::-;2899:5;:8;2905:1;;2899:8;;;;;;;;;;;:17;;;;;;;;;;;;4543:8;2880:36;2862:54;;:15;:54;2854:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;3311:1:::1;3275:13;:25;3289:10;3275:25;;;;;;;;;;;;;;;3269:39;;;;;;;;;;;;;;;;:43;3261:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;3890:8:::2;3915:9;;;;;;;;;;;3911:57;;;3947:9;3941:15;;3911:57;11605:3:::3;;;;;;;;;;;11597:25;;11623:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11597:60;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3998:9:::2;;;;;;;;;;;3994:57;;;4024:15;4035:3;4024:10;:15::i;:::-;3994:57;3335:1;11502:163::o:0;8735:162::-;2635:5;;;;;;;;;;2621:19;;:10;:19;;;2613:28;;;;;;8839:4:::1;8815:6;:12;8822:4;8815:12;;;;;;;;;;;;;;;:21;;;:28;;;;;;;;;;;;;;;;;;8859:30;8869:13;:19;8883:4;8869:19;;;;;;;;;;;;;;;8859:30;;;;;;:::i;:::-;;;;;;;;8735:162:::0;:::o;13328:138::-;13400:7;13432:5;:10;13438:3;13432:10;;;;;;;;;;;:19;;:26;13452:5;13432:26;;;;;;;;;;;;;;;;;;;;;;;;;13425:33;;13328:138;;;;:::o;6784:28::-;;;;;;;;;;;;;:::o;14095:509::-;14182:4;14256:1;14208:6;:12;14215:4;14208:12;;;;;;;;;;;;;;;:24;;:29;14233:3;14208:29;;;;;;;;;;;:44;;;:49;14204:90;;;14281:1;14274:8;;;;14204:90;14306:14;14323:5;:10;14329:3;14323:10;;;;;;;;;;;:24;;;14306:41;;14358:15;14376:5;:10;14382:3;14376:10;;;;;;;;;;;:25;;;14358:43;;14412:16;14431:6;:12;14438:4;14431:12;;;;;;;;;;;;;;;:24;;:29;14456:3;14431:29;;;;;;;;;;;:44;;;14412:63;;14486:15;14559:7;14546:9;14532:10;14521:7;14507:11;:21;14506:36;;;;;;14505:50;14504:62;;;;;;14486:80;;14586:10;14579:17;;;;;;14095:509;;;;;:::o;22567:147::-;22633:13;22671:35;22697:7;22680:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;22671:8;:35::i;:::-;22664:42;;22567:147;;;:::o;4688:40::-;4723:5;4688:40;:::o;8905:1093::-;9032:6;:18;9039:10;9032:18;;;;;;;;;;;;;;;:27;;;;;;;;;;;;9031:28;9023:37;;;;;;9122:19;:56;;;;;;;;;;;;;;;;;;;9246:15;9307:9;9296:20;;9339:26;9417:20;9426:10;9417:8;:20::i;:::-;9453:17;9462:7;9453:8;:17::i;:::-;9375:96;;;;;;;;;:::i;:::-;;;;;;;;;;;;;9339:133;;9483:17;9530:12;9513:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;9503:41;;;;;;9483:61;;9555:20;9595:6;9603:9;9578:35;;;;;;;;;:::i;:::-;;;;;;;;;;;;;9555:58;;9624:20;9657:7;9647:18;;;;;;9624:41;;9678:24;9705:35;9715:12;9729:2;9733;9737;9705:35;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9678:62;;9779:5;;;;;;;;;;9759:25;;:16;:25;;;9836:16;9793:60;;;;;;;;:::i;:::-;;;;;;;;;;;;;9751:104;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;9934:4;9904:6;:18;9911:10;9904:18;;;;;;;;;;;;;;;:27;;;:34;;;;;;;;;;;;;;;;;;9954:36;9964:13;:25;9978:10;9964:25;;;;;;;;;;;;;;;9954:36;;;;;;:::i;:::-;;;;;;;;8905:1093;;;;;;;;;;:::o;11673:147::-;3890:8;3915:9;;;;;;;;;;;3911:57;;;3947:9;3941:15;;3911:57;11751:3:::1;;;;;;;;;;;11743:25;;11769:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11743:69;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3998:9:::0;;;;;;;;;;;3994:57;;;4024:15;4035:3;4024:10;:15::i;:::-;3994:57;11673:147;:::o;22722:143::-;22786:13;22824:33;22850:5;22833:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;22824:8;:33::i;:::-;22817:40;;22722:143;;;:::o;17773:133::-;17846:4;17875:5;:10;17881:3;17875:10;;;;;;;;;;;:23;;;;;;;;;;;;17868:30;;17773:133;;;:::o;6318:17::-;;;;:::o;22873:483::-;22941:13;22972:21;:42;;;;;;;;;;;;;;;;;;;23027:16;23074:1;23060:4;:11;:15;23056:1;:19;23046:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23027:49;;23087:12;:3;23091:1;23087:6;;;;;;;;;;;:12;;;;;;;;;;;23110;:3;23114:1;23110:6;;;;;;;;;;;:12;;;;;;;;;;;23138:6;23133:187;23154:4;:11;23150:1;:15;23133:187;;;23204:8;23235:1;23224:4;23229:1;23224:7;;;;;;;;;;;;;;;;:12;;;;;23218:19;;23213:25;;23204:35;;;;;;;;;;;;;;;;23187:3;23199:1;23195;:5;23191:1;:9;23187:14;;;;;;;;;;;:52;;;;;;;;;;;23271:8;23301:4;23291:14;;:4;23296:1;23291:7;;;;;;;;;;;;;;;;:14;23285:21;;23280:27;;23271:37;;;;;;;;;;;;;;;;23254:3;23266:1;23262;:5;23258:1;:9;23254:14;;;;;;;;;;;:54;;;;;;;;;;;23167:3;;;;;;;23133:187;;;;23344:3;23330:18;;;;22873:483;;;:::o;10444:446::-;10537:7;4629:3;3017:6;:17;;3009:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;3111:6;3065:5;;;;;;;;;;;:15;;;3081:10;3101:4;3065:42;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;3057:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;3184:6;3153:5;;;;;;;;;;;:15;;;3169:10;3153:27;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:37;;3145:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;2750:5:::1;:8;2756:1;;2750:8;;;;;;;;;;;:17;;;;;;;;;;;;4543:8;2731:36;2713:54;;:15;:54;2705:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;3311:1:::2;3275:13;:25;3289:10;3275:25;;;;;;;;;;;;;;;3269:39;;;;;;;;;;;;;;;;:43;3261:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;3890:8:::3;3915:9;;;;;;;;;;;3911:57;;;3947:9;3941:15;;3911:57;10617:3:::4;;;;;;;;;;;10609:25;;10691:7;10700;;10635:73;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10609:100;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10731:1;10726;;:6;10722:161;;;4723:5;10753:7;:22;10749:123;;10796:3;;;;;;;;;;;:17;;;10814:10;10826:5;:8;10832:1;10826:8;;;;;;;;;;;:17;;:29;10844:10;10826:29;;;;;;;;;;;;;;;;10796:60;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;::::0;::::4;;;;;;;;;10749:123;10722:161;3998:9:::3;;;;;;;;;;;3994:57;;;4024:15;4035:3;4024:10;:15::i;:::-;3994:57;3335:1;10444:446:::0;;;;:::o;15027:1548::-;15117:4;15150:1;15143:3;:8;15139:1429;;;15175:6;:12;15182:4;15175:12;;;;;;;;;;;;;;;:24;;:29;15200:3;15175:29;;;;;;;;;;;:44;;;15168:51;;;;15139:1429;15248:1;15241:3;:8;15237:1331;;;15273:6;:12;15280:4;15273:12;;;;;;;;;;;;;;;:24;;:29;15298:3;15273:29;;;;;;;;;;;:40;;;15266:47;;;;15237:1331;15342:1;15335:3;:8;15331:1237;;;15367:6;:12;15374:4;15367:12;;;;;;;;;;;;;;;:24;;:29;15392:3;15367:29;;;;;;;;;;;:39;;;15360:46;;;;15331:1237;15435:1;15428:3;:8;15424:1144;;;15460:6;:12;15467:4;15460:12;;;;;;;;;;;;;;;:24;;:29;15485:3;15460:29;;;;;;;;;;;:43;;;15453:50;;;;15424:1144;15532:1;15525:3;:8;15521:1047;;;15557:6;:12;15564:4;15557:12;;;;;;;;;;;;;;;:24;;:29;15582:3;15557:29;;;;;;;;;;;:35;;;15550:42;;;;15521:1047;15621:1;15614:3;:8;15610:958;;;15646:6;:12;15653:4;15646:12;;;;;;;;;;;;;;;:24;;:29;15671:3;15646:29;;;;;;;;;;;:39;;;15639:46;;;;15610:958;15714:1;15707:3;:8;15703:865;;;15739:6;:12;15746:4;15739:12;;;;;;;;;;;;;;;:24;;:29;15764:3;15739:29;;;;;;;;;;;:42;;;15732:49;;;;15703:865;15810:1;15803:3;:8;15799:769;;;15835:6;:12;15842:4;15835:12;;;;;;;;;;;;;;;:24;;:29;15860:3;15835:29;;;;;;;;;;;:40;;;15828:47;;;;15799:769;15904:1;15897:3;:8;15893:675;;;15929:6;:12;15936:4;15929:12;;;;;;;;;;;;;;;:24;;:29;15954:3;15929:29;;;;;;;;;;;:44;;;15922:51;;;;15893:675;16002:1;15995:3;:8;15991:577;;;16027:6;:12;16034:4;16027:12;;;;;;;;;;;;;;;:24;;:29;16052:3;16027:29;;;;;;;;;;;:41;;;16020:48;;;;15991:577;16097:2;16090:3;:9;16086:482;;;16123:6;:12;16130:4;16123:12;;;;;;;;;;;;;;;:24;;:29;16148:3;16123:29;;;;;;;;;;;:44;;;16116:51;;;;16086:482;16196:2;16189:3;:9;16185:383;;;16222:6;:12;16229:4;16222:12;;;;;;;;;;;;;;;:35;;;16215:42;;;;16185:383;16286:2;16279:3;:9;16275:293;;;16312:6;:12;16319:4;16312:12;;;;;;;;;;;;;;;:26;;;16305:33;;;;16275:293;16367:2;16360:3;:9;16356:212;;;16393:6;:12;16400:4;16393:12;;;;;;;;;;;;;;;:24;;:29;16418:3;16393:29;;;;;;;;;;;:38;;;16386:45;;;;16356:212;16460:2;16453:3;:9;16449:119;;;16486:6;:12;16493:4;16486:12;;;;;;;;;;;;;;;:21;;;;;;;;;;;;:29;;16514:1;16486:29;;;16510:1;16486:29;16479:36;;;;;;16449:119;16555:1;16548:8;;15027:1548;;;;;;:::o;4639:40::-;4673:6;4639:40;:::o;21918:641::-;21989:11;22018:6;22027:1;22018:10;;22039:23;22071:4;22039:37;;22089:463;22100:10;:17;22096:1;:21;22089:463;;;22176:1;22170;22153:10;22164:1;22153:13;;;;;;;;;;;;;;;;:18;;;;;22147:25;;:30;;;22143:372;;;22201:1;22196:6;;;;22143:372;;;22255:3;22249:1;22232:10;22243:1;22232:13;;;;;;;;;;;;;;;;:18;;;;;22226:25;;:32;;;22222:293;;;22282:1;22277:6;;;;22222:293;;;22336:3;22330:1;22313:10;22324:1;22313:13;;;;;;;;;;;;;;;;:18;;;;;22307:25;;:32;;;22303:212;;;22363:1;22358:6;;;;22303:212;;;22417:4;22411:1;22394:10;22405:1;22394:13;;;;;;;;;;;;;;;;:18;;;;;22388:25;;:33;;;22384:131;;;22445:1;22440:6;;;;22384:131;;;22514:1;22509:6;;;;22384:131;22303:212;22222:293;22143:372;22532:8;;;;;;;22089:463;;;21918:641;;;;;:::o;8276:125::-;2635:5;;;;;;;;;;2621:19;;:10;:19;;;2613:28;;;;;;8389:4:::1;8367:19;;:26;;;;;;;;;;;;;;;;;;8276:125:::0;:::o;6344:20::-;;;;:::o;10155:256::-;2635:5;;;;;;;;;;2621:19;;:10;:19;;;2613:28;;;;;;10240:1:::1;10231:6;;:10;10223:19;;;::::0;::::1;;10255:5;;;;;;;;;;;:13;;;10269:19;;;;;;;;;;;10290:6;;10255:42;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;10317:1;10308:6;:10;;;;10358:19;;;;;;;;;;;10329:58;;;10396:5;;;;;;;;;;;10329:74;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;10155:256::o:0;10898:421::-;10982:7;4629:3;3017:6;:17;;3009:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;3111:6;3065:5;;;;;;;;;;;:15;;;3081:10;3101:4;3065:42;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;3057:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;3184:6;3153:5;;;;;;;;;;;:15;;;3169:10;3153:27;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:37;;3145:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;2899:5:::1;:8;2905:1;;2899:8;;;;;;;;;;;:17;;;;;;;;;;;;4543:8;2880:36;2862:54;;:15;:54;2854:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;3311:1:::2;3275:13;:25;3289:10;3275:25;;;;;;;;;;;;;;;3269:39;;;;;;;;;;;;;;;;:43;3261:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;3890:8:::3;3915:9;;;;;;;;;;;3911:57;;;3947:9;3941:15;;3911:57;11064:3:::4;;;;;;;;;;;11056:25;;11129:7;11138;;11082:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11056:91;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11169:1;11164;;:6;11160:152;;;4723:5;11191:7;:22;11187:114;;11234:3;;;;;;;;;;;:8;;;11243:10;11255:5;:8;11261:1;11255:8;;;;;;;;;;;:17;;:29;11273:10;11255:29;;;;;;;;;;;;;;;;11234:51;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;::::0;::::4;;;;;;;;;11187:114;11160:152;3998:9:::3;;;;;;;;;;;3994:57;;;4024:15;4035:3;4024:10;:15::i;:::-;3994:57;3335:1;10898:421:::0;;;;:::o;11867:738::-;11932:19;11953:21;11976:29;12007:22;12031:23;12056:19;12093:15;12111:5;:8;12117:1;;12111:8;;;;;;;;;;;:16;;;;;;;;;;;;12093:34;;12138:12;12153:5;:8;12159:1;;12153:8;;;;;;;;;;;:13;;;;;;;;;;;;12138:28;;12177:12;12192:5;:8;12198:1;;12192:8;;;;;;;;;;;:19;;;;;;;;;;;;12177:34;;12222:20;12259:6;:12;12266:4;12259:12;;;;;;;;;;;;;;;:21;;;;;;;;;;;;12255:147;;;12306:13;:19;12320:4;12306:19;;;;;;;;;;;;;;;12297:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12255:147;;;12367:6;:12;12374:4;12367:12;;;;;;;;;;;;;;;:23;;12358:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12255:147;12432:13;:19;12446:4;12432:19;;;;;;;;;;;;;;;12462:6;12479:14;12504:13;:22;12518:7;12504:22;;;;;;;;;;;;;;;12537:13;:19;12551:4;12537:19;;;;;;;;;;;;;;;12567:13;:19;12581:4;12567:19;;;;;;;;;;;;;;;12414:183;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11867:738;;;;;;;:::o;21243:171::-;21354:18;21367:4;;21354:12;:18::i;:::-;21383:23;21395:2;21399;21403;21383:11;:23::i;:::-;21243:171;;;;;:::o;16883:882::-;16958:4;16991:1;16984:3;:8;16980:778;;;17016:5;:10;17022:3;17016:10;;;;;;;;;;;:22;;;;;;;;;;;;17009:29;;;;;;16980:778;17067:1;17060:3;:8;17056:702;;;17092:5;:10;17098:3;17092:10;;;;;;;;;;;:16;;;;;;;;;;;;17085:23;;;;;;17056:702;17137:1;17130:3;:8;17126:632;;;17162:5;:10;17168:3;17162:10;;;;;;;;;;;:19;;;;;;;;;;;;17155:26;;;;;;17126:632;17210:1;17203:3;:8;17199:559;;;17235:5;:10;17241:3;17235:10;;;;;;;;;;;:22;;;17228:29;;;;17199:559;17286:1;17279:3;:8;17275:483;;;17311:5;:10;17317:3;17311:10;;;;;;;;;;;:25;;;17304:32;;;;17275:483;17365:1;17358:3;:8;17354:404;;;17390:5;:10;17396:3;17390:10;;;;;;;;;;;:24;;;17383:31;;;;17354:404;17443:1;17436:3;:8;17432:326;;;17468:5;:10;17474:3;17468:10;;;;;;;;;;;:14;;;;;;;;;;;;17461:21;;;;;;17432:326;17511:1;17504:3;:8;17500:258;;;17536:5;:10;17542:3;17536:10;;;;;;;;;;;:22;;;17529:29;;;;17500:258;17587:1;17580:3;:8;17576:182;;;17612:5;:10;17618:3;17612:10;;;;;;;;;;;:22;;;17605:29;;;;17576:182;17663:1;17656:3;:8;17652:106;;;17688:5;:10;17694:3;17688:10;;;;;;;;;;;:17;;;17681:24;;;;17652:106;17745:1;17738:8;;16883:882;;;;;:::o;8409:98::-;2635:5;;;;;;;;;;2621:19;;:10;:19;;;2613:28;;;;;;8496:3:::1;8484:9;;:15;;;;;;;;;;;;;;;;;;8409:98:::0;:::o;6526:18::-;;;;:::o;6115:47::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;11327:167::-;2899:5;:8;2905:1;;2899:8;;;;;;;;;;;:17;;;;;;;;;;;;4543:8;2880:36;2862:54;;:15;:54;2854:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;3311:1:::1;3275:13;:25;3289:10;3275:25;;;;;;;;;;;;;;;3269:39;;;;;;;;;;;;;;;;:43;3261:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;3890:8:::2;3915:9;;;;;;;;;;;3911:57;;;3947:9;3941:15;;3911:57;11432:3:::3;;;;;;;;;;;11424:25;;11450:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11424:62;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3998:9:::2;;;;;;;;;;;3994:57;;;4024:15;4035:3;4024:10;:15::i;:::-;3994:57;3335:1;11327:167::o:0;10006:141::-;2635:5;;;;;;;;;;2621:19;;:10;:19;;;2613:28;;;;;;10124:15:::1;;10107:14;:32;;;;;;;:::i;:::-;;10006:141:::0;;:::o;12613:376::-;12691:14;12707:11;12720:15;12737:16;12755:14;12790:19;12821:3;;;;;;;;;;;12813:25;;12896:4;12902:9;12839:73;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12813:100;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12787:126;;;12942:6;12931:50;;;;;;;;;;;;:::i;:::-;12924:57;;;;;;;;;;;12613:376;;;;;;;;:::o;13510:577::-;13589:4;13595;13601;13607;13613;13619;13625;13631;13637;13659:31;13693:6;:12;13700:4;13693:12;;;;;;;;;;;;;;;:24;;:29;13718:3;13693:29;;;;;;;;;;;13659:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13760:12;:18;;;13789:33;13812:4;13818:3;13789:22;:33::i;:::-;13833:12;:22;;;13866:12;:25;;;13902:12;:23;;;13936:12;:27;;;13974:12;:24;;;14009:12;:27;;;14047:12;:21;;;13733:346;;;;;;;;;;;;;;;;;;;13510:577;;;;;;;;;;;:::o;12997:323::-;13045:8;13055:10;13067:9;13078:8;13088:9;13099:11;13112:12;13145:19;13176:3;;;;;;;;;;;13168:25;;13194:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13168:64;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13142:90;;;13261:6;13250:62;;;;;;;;;;;;:::i;:::-;13243:69;;;;;;;;;;;;;;;12997:323;;;;;;;:::o;21422:488::-;21499:4;21573:6;21568:313;21585:4;:11;21581:1;:15;21568:313;;;21618:11;21632:4;21637:1;21632:7;;;;;;;;;;;;;;;;21618:21;;21686:4;21678:12;;:4;:12;;;;;:28;;;;;21702:4;21694:12;;:4;:12;;;;;21678:28;21676:31;:85;;;;;21740:4;21732:12;;:4;:12;;;;;:28;;;;;21756:4;21748:12;;:4;:12;;;;;21732:28;21730:31;21676:85;:139;;;;;21794:4;21786:12;;:4;:12;;;;;:28;;;;;21810:4;21802:12;;:4;:12;;;;;21786:28;21784:31;21676:139;21654:215;;;21864:5;21857:12;;;;;;21654:215;21568:313;21598:3;;;;;;;21568:313;;;;21898:4;21891:11;;21422:488;;;;:::o;17963:447::-;18025:9;18041;;;;;;;;;;;:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18023:45;;;;;;18398:4;18389:5;18369:11;18360:5;18348:9;18342:3;:15;:23;18341:39;18340:55;:62;;;;;;18294:6;:18;18301:10;18294:18;;;;;;;;;;;;;;;:30;;:33;18325:1;;18294:33;;;;;;;;;;;:42;;;:108;;;;;;;;;;;17963:447;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:342:1:-;;109:64;124:48;165:6;124:48;:::i;:::-;109:64;:::i;:::-;100:73;;196:6;189:5;182:21;234:4;227:5;223:16;272:3;263:6;258:3;254:16;251:25;248:2;;;289:1;286;279:12;248:2;302:41;336:6;331:3;326;302:41;:::i;:::-;90:259;;;;;;:::o;355:344::-;;458:65;473:49;515:6;473:49;:::i;:::-;458:65;:::i;:::-;449:74;;546:6;539:5;532:21;584:4;577:5;573:16;622:3;613:6;608:3;604:16;601:25;598:2;;;639:1;636;629:12;598:2;652:41;686:6;681:3;676;652:41;:::i;:::-;439:260;;;;;;:::o;705:139::-;;789:6;776:20;767:29;;805:33;832:5;805:33;:::i;:::-;757:87;;;;:::o;850:133::-;;931:6;918:20;909:29;;947:30;971:5;947:30;:::i;:::-;899:84;;;;:::o;989:139::-;;1073:6;1060:20;1051:29;;1089:33;1116:5;1089:33;:::i;:::-;1041:87;;;;:::o;1147:271::-;;1251:3;1244:4;1236:6;1232:17;1228:27;1218:2;;1269:1;1266;1259:12;1218:2;1309:6;1296:20;1334:78;1408:3;1400:6;1393:4;1385:6;1381:17;1334:78;:::i;:::-;1325:87;;1208:210;;;;;:::o;1424:141::-;;1511:6;1505:13;1496:22;;1527:32;1553:5;1527:32;:::i;:::-;1486:79;;;;:::o;1571:133::-;;1652:6;1639:20;1630:29;;1668:30;1692:5;1668:30;:::i;:::-;1620:84;;;;:::o;1724:352::-;;;1842:3;1835:4;1827:6;1823:17;1819:27;1809:2;;1860:1;1857;1850:12;1809:2;1896:6;1883:20;1873:30;;1926:18;1918:6;1915:30;1912:2;;;1958:1;1955;1948:12;1912:2;1995:4;1987:6;1983:17;1971:29;;2049:3;2041:4;2033:6;2029:17;2019:8;2015:32;2012:41;2009:2;;;2066:1;2063;2056:12;2009:2;1799:277;;;;;:::o;2096:273::-;;2201:3;2194:4;2186:6;2182:17;2178:27;2168:2;;2219:1;2216;2209:12;2168:2;2259:6;2246:20;2284:79;2359:3;2351:6;2344:4;2336:6;2332:17;2284:79;:::i;:::-;2275:88;;2158:211;;;;;:::o;2375:139::-;;2459:6;2446:20;2437:29;;2475:33;2502:5;2475:33;:::i;:::-;2427:87;;;;:::o;2520:143::-;;2608:6;2602:13;2593:22;;2624:33;2651:5;2624:33;:::i;:::-;2583:80;;;;:::o;2669:135::-;;2751:6;2738:20;2729:29;;2767:31;2792:5;2767:31;:::i;:::-;2719:85;;;;:::o;2810:141::-;;2897:6;2891:13;2882:22;;2913:32;2939:5;2913:32;:::i;:::-;2872:79;;;;:::o;2957:262::-;;3065:2;3053:9;3044:7;3040:23;3036:32;3033:2;;;3081:1;3078;3071:12;3033:2;3124:1;3149:53;3194:7;3185:6;3174:9;3170:22;3149:53;:::i;:::-;3139:63;;3095:117;3023:196;;;;:::o;3225:407::-;;;3350:2;3338:9;3329:7;3325:23;3321:32;3318:2;;;3366:1;3363;3356:12;3318:2;3409:1;3434:53;3479:7;3470:6;3459:9;3455:22;3434:53;:::i;:::-;3424:63;;3380:117;3536:2;3562:53;3607:7;3598:6;3587:9;3583:22;3562:53;:::i;:::-;3552:63;;3507:118;3308:324;;;;;:::o;3638:552::-;;;;3780:2;3768:9;3759:7;3755:23;3751:32;3748:2;;;3796:1;3793;3786:12;3748:2;3839:1;3864:53;3909:7;3900:6;3889:9;3885:22;3864:53;:::i;:::-;3854:63;;3810:117;3966:2;3992:53;4037:7;4028:6;4017:9;4013:22;3992:53;:::i;:::-;3982:63;;3937:118;4094:2;4120:53;4165:7;4156:6;4145:9;4141:22;4120:53;:::i;:::-;4110:63;;4065:118;3738:452;;;;;:::o;4196:256::-;;4301:2;4289:9;4280:7;4276:23;4272:32;4269:2;;;4317:1;4314;4307:12;4269:2;4360:1;4385:50;4427:7;4418:6;4407:9;4403:22;4385:50;:::i;:::-;4375:60;;4331:114;4259:193;;;;:::o;4458:373::-;;4575:2;4563:9;4554:7;4550:23;4546:32;4543:2;;;4591:1;4588;4581:12;4543:2;4662:1;4651:9;4647:17;4634:31;4692:18;4684:6;4681:30;4678:2;;;4724:1;4721;4714:12;4678:2;4752:62;4806:7;4797:6;4786:9;4782:22;4752:62;:::i;:::-;4742:72;;4605:219;4533:298;;;;:::o;4837:395::-;;;4965:2;4953:9;4944:7;4940:23;4936:32;4933:2;;;4981:1;4978;4971:12;4933:2;5052:1;5041:9;5037:17;5024:31;5082:18;5074:6;5071:30;5068:2;;;5114:1;5111;5104:12;5068:2;5150:65;5207:7;5198:6;5187:9;5183:22;5150:65;:::i;:::-;5132:83;;;;4995:230;4923:309;;;;;:::o;5238:827::-;;;;;;5415:3;5403:9;5394:7;5390:23;5386:33;5383:2;;;5432:1;5429;5422:12;5383:2;5503:1;5492:9;5488:17;5475:31;5533:18;5525:6;5522:30;5519:2;;;5565:1;5562;5555:12;5519:2;5601:65;5658:7;5649:6;5638:9;5634:22;5601:65;:::i;:::-;5583:83;;;;5446:230;5715:2;5741:51;5784:7;5775:6;5764:9;5760:22;5741:51;:::i;:::-;5731:61;;5686:116;5841:2;5867:53;5912:7;5903:6;5892:9;5888:22;5867:53;:::i;:::-;5857:63;;5812:118;5969:2;5995:53;6040:7;6031:6;6020:9;6016:22;5995:53;:::i;:::-;5985:63;;5940:118;5373:692;;;;;;;;:::o;6071:375::-;;6189:2;6177:9;6168:7;6164:23;6160:32;6157:2;;;6205:1;6202;6195:12;6157:2;6276:1;6265:9;6261:17;6248:31;6306:18;6298:6;6295:30;6292:2;;;6338:1;6335;6328:12;6292:2;6366:63;6421:7;6412:6;6401:9;6397:22;6366:63;:::i;:::-;6356:73;;6219:220;6147:299;;;;:::o;6452:262::-;;6560:2;6548:9;6539:7;6535:23;6531:32;6528:2;;;6576:1;6573;6566:12;6528:2;6619:1;6644:53;6689:7;6680:6;6669:9;6665:22;6644:53;:::i;:::-;6634:63;;6590:117;6518:196;;;;:::o;6720:284::-;;6839:2;6827:9;6818:7;6814:23;6810:32;6807:2;;;6855:1;6852;6845:12;6807:2;6898:1;6923:64;6979:7;6970:6;6959:9;6955:22;6923:64;:::i;:::-;6913:74;;6869:128;6797:207;;;;:::o;7010:407::-;;;7135:2;7123:9;7114:7;7110:23;7106:32;7103:2;;;7151:1;7148;7141:12;7103:2;7194:1;7219:53;7264:7;7255:6;7244:9;7240:22;7219:53;:::i;:::-;7209:63;;7165:117;7321:2;7347:53;7392:7;7383:6;7372:9;7368:22;7347:53;:::i;:::-;7337:63;;7292:118;7093:324;;;;;:::o;7423:401::-;;;7545:2;7533:9;7524:7;7520:23;7516:32;7513:2;;;7561:1;7558;7551:12;7513:2;7604:1;7629:53;7674:7;7665:6;7654:9;7650:22;7629:53;:::i;:::-;7619:63;;7575:117;7731:2;7757:50;7799:7;7790:6;7779:9;7775:22;7757:50;:::i;:::-;7747:60;;7702:115;7503:321;;;;;:::o;7830:540::-;;;;7975:2;7963:9;7954:7;7950:23;7946:32;7943:2;;;7991:1;7988;7981:12;7943:2;8034:1;8059:53;8104:7;8095:6;8084:9;8080:22;8059:53;:::i;:::-;8049:63;;8005:117;8189:2;8178:9;8174:18;8161:32;8220:18;8212:6;8209:30;8206:2;;;8252:1;8249;8242:12;8206:2;8288:65;8345:7;8336:6;8325:9;8321:22;8288:65;:::i;:::-;8270:83;;;;8132:231;7933:437;;;;;:::o;8376:407::-;;;8501:2;8489:9;8480:7;8476:23;8472:32;8469:2;;;8517:1;8514;8507:12;8469:2;8560:1;8585:53;8630:7;8621:6;8610:9;8606:22;8585:53;:::i;:::-;8575:63;;8531:117;8687:2;8713:53;8758:7;8749:6;8738:9;8734:22;8713:53;:::i;:::-;8703:63;;8658:118;8459:324;;;;;:::o;8789:910::-;;;;;;8976:3;8964:9;8955:7;8951:23;8947:33;8944:2;;;8993:1;8990;8983:12;8944:2;9036:1;9061:64;9117:7;9108:6;9097:9;9093:22;9061:64;:::i;:::-;9051:74;;9007:128;9174:2;9200:64;9256:7;9247:6;9236:9;9232:22;9200:64;:::i;:::-;9190:74;;9145:129;9313:2;9339:64;9395:7;9386:6;9375:9;9371:22;9339:64;:::i;:::-;9329:74;;9284:129;9452:2;9478:64;9534:7;9525:6;9514:9;9510:22;9478:64;:::i;:::-;9468:74;;9423:129;9591:3;9618:64;9674:7;9665:6;9654:9;9650:22;9618:64;:::i;:::-;9608:74;;9562:130;8934:765;;;;;;;;:::o;9705:1224::-;;;;;;;;9926:3;9914:9;9905:7;9901:23;9897:33;9894:2;;;9943:1;9940;9933:12;9894:2;9986:1;10011:64;10067:7;10058:6;10047:9;10043:22;10011:64;:::i;:::-;10001:74;;9957:128;10124:2;10150:64;10206:7;10197:6;10186:9;10182:22;10150:64;:::i;:::-;10140:74;;10095:129;10263:2;10289:64;10345:7;10336:6;10325:9;10321:22;10289:64;:::i;:::-;10279:74;;10234:129;10402:2;10428:64;10484:7;10475:6;10464:9;10460:22;10428:64;:::i;:::-;10418:74;;10373:129;10541:3;10568:64;10624:7;10615:6;10604:9;10600:22;10568:64;:::i;:::-;10558:74;;10512:130;10681:3;10708:64;10764:7;10755:6;10744:9;10740:22;10708:64;:::i;:::-;10698:74;;10652:130;10821:3;10848:64;10904:7;10895:6;10884:9;10880:22;10848:64;:::i;:::-;10838:74;;10792:130;9884:1045;;;;;;;;;;:::o;10935:904::-;;;;;;11119:3;11107:9;11098:7;11094:23;11090:33;11087:2;;;11136:1;11133;11126:12;11087:2;11179:1;11204:63;11259:7;11250:6;11239:9;11235:22;11204:63;:::i;:::-;11194:73;;11150:127;11316:2;11342:63;11397:7;11388:6;11377:9;11373:22;11342:63;:::i;:::-;11332:73;;11287:128;11454:2;11480:64;11536:7;11527:6;11516:9;11512:22;11480:64;:::i;:::-;11470:74;;11425:129;11593:2;11619:64;11675:7;11666:6;11655:9;11651:22;11619:64;:::i;:::-;11609:74;;11564:129;11732:3;11759:63;11814:7;11805:6;11794:9;11790:22;11759:63;:::i;:::-;11749:73;;11703:129;11077:762;;;;;;;;:::o;11845:548::-;;;;11985:2;11973:9;11964:7;11960:23;11956:32;11953:2;;;12001:1;11998;11991:12;11953:2;12044:1;12069:51;12112:7;12103:6;12092:9;12088:22;12069:51;:::i;:::-;12059:61;;12015:115;12169:2;12195:53;12240:7;12231:6;12220:9;12216:22;12195:53;:::i;:::-;12185:63;;12140:118;12297:2;12323:53;12368:7;12359:6;12348:9;12344:22;12323:53;:::i;:::-;12313:63;;12268:118;11943:450;;;;;:::o;12399:147::-;12494:45;12533:5;12494:45;:::i;:::-;12489:3;12482:58;12472:74;;:::o;12552:118::-;12639:24;12657:5;12639:24;:::i;:::-;12634:3;12627:37;12617:53;;:::o;12676:157::-;12781:45;12801:24;12819:5;12801:24;:::i;:::-;12781:45;:::i;:::-;12776:3;12769:58;12759:74;;:::o;12839:109::-;12920:21;12935:5;12920:21;:::i;:::-;12915:3;12908:34;12898:50;;:::o;12954:118::-;13041:24;13059:5;13041:24;:::i;:::-;13036:3;13029:37;13019:53;;:::o;13078:157::-;13183:45;13203:24;13221:5;13203:24;:::i;:::-;13183:45;:::i;:::-;13178:3;13171:58;13161:74;;:::o;13241:373::-;;13373:38;13405:5;13373:38;:::i;:::-;13427:88;13508:6;13503:3;13427:88;:::i;:::-;13420:95;;13524:52;13569:6;13564:3;13557:4;13550:5;13546:16;13524:52;:::i;:::-;13601:6;13596:3;13592:16;13585:23;;13349:265;;;;;:::o;13620:109::-;13701:21;13716:5;13701:21;:::i;:::-;13696:3;13689:34;13679:50;;:::o;13759:304::-;;13878:71;13942:6;13937:3;13878:71;:::i;:::-;13871:78;;13959:43;13995:6;13990:3;13983:5;13959:43;:::i;:::-;14027:29;14049:6;14027:29;:::i;:::-;14022:3;14018:39;14011:46;;13861:202;;;;;:::o;14093:317::-;;14230:89;14312:6;14307:3;14230:89;:::i;:::-;14223:96;;14329:43;14365:6;14360:3;14353:5;14329:43;:::i;:::-;14397:6;14392:3;14388:16;14381:23;;14213:197;;;;;:::o;14416:364::-;;14532:39;14565:5;14532:39;:::i;:::-;14587:71;14651:6;14646:3;14587:71;:::i;:::-;14580:78;;14667:52;14712:6;14707:3;14700:4;14693:5;14689:16;14667:52;:::i;:::-;14744:29;14766:6;14744:29;:::i;:::-;14739:3;14735:39;14728:46;;14508:272;;;;;:::o;14786:377::-;;14920:39;14953:5;14920:39;:::i;:::-;14975:89;15057:6;15052:3;14975:89;:::i;:::-;14968:96;;15073:52;15118:6;15113:3;15106:4;15099:5;15095:16;15073:52;:::i;:::-;15150:6;15145:3;15141:16;15134:23;;14896:267;;;;;:::o;15193:937::-;;15315:5;15309:12;15352:1;15341:9;15337:17;15368:1;15363:281;;;;15658:1;15653:471;;;;15330:794;;15363:281;15453:4;15449:1;15438:9;15434:17;15430:28;15478:71;15542:6;15537:3;15478:71;:::i;:::-;15471:78;;15593:4;15589:9;15578;15574:25;15569:3;15562:38;15629:4;15624:3;15620:14;15613:21;;15370:274;15363:281;;15653:471;15734:1;15723:9;15719:17;15756:71;15820:6;15815:3;15756:71;:::i;:::-;15749:78;;15855:38;15887:5;15855:38;:::i;:::-;15915:1;15929:154;15943:6;15940:1;15937:13;15929:154;;;16017:7;16011:14;16007:1;16002:3;15998:11;15991:35;16067:1;16058:7;16054:15;16043:26;;15965:4;15962:1;15958:12;15953:17;;15929:154;;;16112:1;16107:3;16103:11;16096:18;;15660:464;;;15330:794;;15282:848;;;;;:::o;16136:312::-;;16299:67;16363:2;16358:3;16299:67;:::i;:::-;16292:74;;16396:16;16392:1;16387:3;16383:11;16376:37;16439:2;16434:3;16430:12;16423:19;;16282:166;;;:::o;16454:314::-;;16617:67;16681:2;16676:3;16617:67;:::i;:::-;16610:74;;16714:18;16710:1;16705:3;16701:11;16694:39;16759:2;16754:3;16750:12;16743:19;;16600:168;;;:::o;16774:355::-;;16955:85;17037:2;17032:3;16955:85;:::i;:::-;16948:92;;17070:23;17066:1;17061:3;17057:11;17050:44;17120:2;17115:3;17111:12;17104:19;;16938:191;;;:::o;17135:310::-;;17298:67;17362:2;17357:3;17298:67;:::i;:::-;17291:74;;17395:14;17391:1;17386:3;17382:11;17375:35;17436:2;17431:3;17427:12;17420:19;;17281:164;;;:::o;17451:305::-;;17614:66;17678:1;17673:3;17614:66;:::i;:::-;17607:73;;17710:10;17706:1;17701:3;17697:11;17690:31;17747:2;17742:3;17738:12;17731:19;;17597:159;;;:::o;17762:304::-;;17925:66;17989:1;17984:3;17925:66;:::i;:::-;17918:73;;18021:9;18017:1;18012:3;18008:11;18001:30;18057:2;18052:3;18048:12;18041:19;;17908:158;;;:::o;18072:356::-;;18253:85;18335:2;18330:3;18253:85;:::i;:::-;18246:92;;18368:24;18364:1;18359:3;18355:11;18348:45;18419:2;18414:3;18410:12;18403:19;;18236:192;;;:::o;18434:344::-;;18615:85;18697:2;18692:3;18615:85;:::i;:::-;18608:92;;18730:12;18726:1;18721:3;18717:11;18710:33;18769:2;18764:3;18760:12;18753:19;;18598:180;;;:::o;18784:304::-;;18947:66;19011:1;19006:3;18947:66;:::i;:::-;18940:73;;19043:9;19039:1;19034:3;19030:11;19023:30;19079:2;19074:3;19070:12;19063:19;;18930:158;;;:::o;19094:118::-;19181:24;19199:5;19181:24;:::i;:::-;19176:3;19169:37;19159:53;;:::o;19218:157::-;19323:45;19343:24;19361:5;19343:24;:::i;:::-;19323:45;:::i;:::-;19318:3;19311:58;19301:74;;:::o;19381:112::-;19464:22;19480:5;19464:22;:::i;:::-;19459:3;19452:35;19442:51;;:::o;19499:256::-;;19626:75;19697:3;19688:6;19626:75;:::i;:::-;19726:2;19721:3;19717:12;19710:19;;19746:3;19739:10;;19615:140;;;;:::o;19761:271::-;;19913:93;20002:3;19993:6;19913:93;:::i;:::-;19906:100;;20023:3;20016:10;;19895:137;;;;:::o;20038:412::-;;20218:93;20307:3;20298:6;20218:93;:::i;:::-;20211:100;;20321:75;20392:3;20383:6;20321:75;:::i;:::-;20421:2;20416:3;20412:12;20405:19;;20441:3;20434:10;;20200:250;;;;;:::o;20456:295::-;;20620:105;20721:3;20712:6;20704;20620:105;:::i;:::-;20613:112;;20742:3;20735:10;;20602:149;;;;;:::o;20757:275::-;;20911:95;21002:3;20993:6;20911:95;:::i;:::-;20904:102;;21023:3;21016:10;;20893:139;;;;:::o;21038:967::-;;21442:148;21586:3;21442:148;:::i;:::-;21435:155;;21607:95;21698:3;21689:6;21607:95;:::i;:::-;21600:102;;21719:148;21863:3;21719:148;:::i;:::-;21712:155;;21884:95;21975:3;21966:6;21884:95;:::i;:::-;21877:102;;21996:3;21989:10;;21424:581;;;;;:::o;22011:522::-;;22246:148;22390:3;22246:148;:::i;:::-;22239:155;;22404:75;22475:3;22466:6;22404:75;:::i;:::-;22504:2;22499:3;22495:12;22488:19;;22524:3;22517:10;;22228:305;;;;:::o;22539:256::-;;22666:75;22737:3;22728:6;22666:75;:::i;:::-;22766:2;22761:3;22757:12;22750:19;;22786:3;22779:10;;22655:140;;;;:::o;22801:222::-;;22932:2;22921:9;22917:18;22909:26;;22945:71;23013:1;23002:9;22998:17;22989:6;22945:71;:::i;:::-;22899:124;;;;:::o;23029:238::-;;23168:2;23157:9;23153:18;23145:26;;23181:79;23257:1;23246:9;23242:17;23233:6;23181:79;:::i;:::-;23135:132;;;;:::o;23273:348::-;;23440:2;23429:9;23425:18;23417:26;;23453:79;23529:1;23518:9;23514:17;23505:6;23453:79;:::i;:::-;23542:72;23610:2;23599:9;23595:18;23586:6;23542:72;:::i;:::-;23407:214;;;;;:::o;23627:348::-;;23794:2;23783:9;23779:18;23771:26;;23807:79;23883:1;23872:9;23868:17;23859:6;23807:79;:::i;:::-;23896:72;23964:2;23953:9;23949:18;23940:6;23896:72;:::i;:::-;23761:214;;;;;:::o;23981:332::-;;24140:2;24129:9;24125:18;24117:26;;24153:71;24221:1;24210:9;24206:17;24197:6;24153:71;:::i;:::-;24234:72;24302:2;24291:9;24287:18;24278:6;24234:72;:::i;:::-;24107:206;;;;;:::o;24319:210::-;;24444:2;24433:9;24429:18;24421:26;;24457:65;24519:1;24508:9;24504:17;24495:6;24457:65;:::i;:::-;24411:118;;;;:::o;24535:545::-;;24746:3;24735:9;24731:19;24723:27;;24760:71;24828:1;24817:9;24813:17;24804:6;24760:71;:::i;:::-;24841:68;24905:2;24894:9;24890:18;24881:6;24841:68;:::i;:::-;24919:72;24987:2;24976:9;24972:18;24963:6;24919:72;:::i;:::-;25001;25069:2;25058:9;25054:18;25045:6;25001:72;:::i;:::-;24713:367;;;;;;;:::o;25086:210::-;;25211:2;25200:9;25196:18;25188:26;;25224:65;25286:1;25275:9;25271:17;25262:6;25224:65;:::i;:::-;25178:118;;;;:::o;25302:313::-;;25453:2;25442:9;25438:18;25430:26;;25502:9;25496:4;25492:20;25488:1;25477:9;25473:17;25466:47;25530:78;25603:4;25594:6;25530:78;:::i;:::-;25522:86;;25420:195;;;;:::o;25621:1321::-;;26012:3;26001:9;25997:19;25989:27;;26062:9;26056:4;26052:20;26048:1;26037:9;26033:17;26026:47;26090:78;26163:4;26154:6;26090:78;:::i;:::-;26082:86;;26215:9;26209:4;26205:20;26200:2;26189:9;26185:18;26178:48;26243:78;26316:4;26307:6;26243:78;:::i;:::-;26235:86;;26368:9;26362:4;26358:20;26353:2;26342:9;26338:18;26331:48;26396:78;26469:4;26460:6;26396:78;:::i;:::-;26388:86;;26521:9;26515:4;26511:20;26506:2;26495:9;26491:18;26484:48;26549:78;26622:4;26613:6;26549:78;:::i;:::-;26541:86;;26675:9;26669:4;26665:20;26659:3;26648:9;26644:19;26637:49;26703:78;26776:4;26767:6;26703:78;:::i;:::-;26695:86;;26829:9;26823:4;26819:20;26813:3;26802:9;26798:19;26791:49;26857:78;26930:4;26921:6;26857:78;:::i;:::-;26849:86;;25979:963;;;;;;;;;:::o;26948:307::-;;27096:2;27085:9;27081:18;27073:26;;27145:9;27139:4;27135:20;27131:1;27120:9;27116:17;27109:47;27173:75;27243:4;27234:6;27173:75;:::i;:::-;27165:83;;27063:192;;;;:::o;27261:419::-;;27465:2;27454:9;27450:18;27442:26;;27514:9;27508:4;27504:20;27500:1;27489:9;27485:17;27478:47;27542:131;27668:4;27542:131;:::i;:::-;27534:139;;27432:248;;;:::o;27686:419::-;;27890:2;27879:9;27875:18;27867:26;;27939:9;27933:4;27929:20;27925:1;27914:9;27910:17;27903:47;27967:131;28093:4;27967:131;:::i;:::-;27959:139;;27857:248;;;:::o;28111:419::-;;28315:2;28304:9;28300:18;28292:26;;28364:9;28358:4;28354:20;28350:1;28339:9;28335:17;28328:47;28392:131;28518:4;28392:131;:::i;:::-;28384:139;;28282:248;;;:::o;28536:419::-;;28740:2;28729:9;28725:18;28717:26;;28789:9;28783:4;28779:20;28775:1;28764:9;28760:17;28753:47;28817:131;28943:4;28817:131;:::i;:::-;28809:139;;28707:248;;;:::o;28961:419::-;;29165:2;29154:9;29150:18;29142:26;;29214:9;29208:4;29204:20;29200:1;29189:9;29185:17;29178:47;29242:131;29368:4;29242:131;:::i;:::-;29234:139;;29132:248;;;:::o;29386:419::-;;29590:2;29579:9;29575:18;29567:26;;29639:9;29633:4;29629:20;29625:1;29614:9;29610:17;29603:47;29667:131;29793:4;29667:131;:::i;:::-;29659:139;;29557:248;;;:::o;29811:222::-;;29942:2;29931:9;29927:18;29919:26;;29955:71;30023:1;30012:9;30008:17;29999:6;29955:71;:::i;:::-;29909:124;;;;:::o;30039:443::-;;30228:2;30217:9;30213:18;30205:26;;30241:71;30309:1;30298:9;30294:17;30285:6;30241:71;:::i;:::-;30359:9;30353:4;30349:20;30344:2;30333:9;30329:18;30322:48;30387:88;30470:4;30461:6;30453;30387:88;:::i;:::-;30379:96;;30195:287;;;;;;:::o;30488:664::-;;30731:3;30720:9;30716:19;30708:27;;30745:71;30813:1;30802:9;30798:17;30789:6;30745:71;:::i;:::-;30826:72;30894:2;30883:9;30879:18;30870:6;30826:72;:::i;:::-;30908;30976:2;30965:9;30961:18;30952:6;30908:72;:::i;:::-;30990;31058:2;31047:9;31043:18;31034:6;30990:72;:::i;:::-;31072:73;31140:3;31129:9;31125:19;31116:6;31072:73;:::i;:::-;30698:454;;;;;;;;:::o;31158:886::-;;31457:3;31446:9;31442:19;31434:27;;31471:71;31539:1;31528:9;31524:17;31515:6;31471:71;:::i;:::-;31552:72;31620:2;31609:9;31605:18;31596:6;31552:72;:::i;:::-;31634;31702:2;31691:9;31687:18;31678:6;31634:72;:::i;:::-;31716;31784:2;31773:9;31769:18;31760:6;31716:72;:::i;:::-;31798:73;31866:3;31855:9;31851:19;31842:6;31798:73;:::i;:::-;31881;31949:3;31938:9;31934:19;31925:6;31881:73;:::i;:::-;31964;32032:3;32021:9;32017:19;32008:6;31964:73;:::i;:::-;31424:620;;;;;;;;;;:::o;32050:1108::-;;32405:3;32394:9;32390:19;32382:27;;32419:71;32487:1;32476:9;32472:17;32463:6;32419:71;:::i;:::-;32500:72;32568:2;32557:9;32553:18;32544:6;32500:72;:::i;:::-;32582;32650:2;32639:9;32635:18;32626:6;32582:72;:::i;:::-;32664;32732:2;32721:9;32717:18;32708:6;32664:72;:::i;:::-;32746:73;32814:3;32803:9;32799:19;32790:6;32746:73;:::i;:::-;32829;32897:3;32886:9;32882:19;32873:6;32829:73;:::i;:::-;32912;32980:3;32969:9;32965:19;32956:6;32912:73;:::i;:::-;32995;33063:3;33052:9;33048:19;33039:6;32995:73;:::i;:::-;33078;33146:3;33135:9;33131:19;33122:6;33078:73;:::i;:::-;32372:786;;;;;;;;;;;;:::o;33164:278::-;;33230:2;33224:9;33214:19;;33272:4;33264:6;33260:17;33379:6;33367:10;33364:22;33343:18;33331:10;33328:34;33325:62;33322:2;;;33390:13;;:::i;:::-;33322:2;33425:10;33421:2;33414:22;33204:238;;;;:::o;33448:326::-;;33599:18;33591:6;33588:30;33585:2;;;33621:13;;:::i;:::-;33585:2;33701:4;33697:9;33690:4;33682:6;33678:17;33674:33;33666:41;;33762:4;33756;33752:15;33744:23;;33514:260;;;:::o;33780:327::-;;33932:18;33924:6;33921:30;33918:2;;;33954:13;;:::i;:::-;33918:2;34034:4;34030:9;34023:4;34015:6;34011:17;34007:33;33999:41;;34095:4;34089;34085:15;34077:23;;33847:260;;;:::o;34113:141::-;;34185:3;34177:11;;34208:3;34205:1;34198:14;34242:4;34239:1;34229:18;34221:26;;34167:87;;;:::o;34260:98::-;;34345:5;34339:12;34329:22;;34318:40;;;:::o;34364:99::-;;34450:5;34444:12;34434:22;;34423:40;;;:::o;34469:147::-;;34607:3;34592:18;;34582:34;;;;:::o;34622:169::-;;34740:6;34735:3;34728:19;34780:4;34775:3;34771:14;34756:29;;34718:73;;;;:::o;34797:148::-;;34936:3;34921:18;;34911:34;;;;:::o;34951:96::-;;35017:24;35035:5;35017:24;:::i;:::-;35006:35;;34996:51;;;:::o;35053:90::-;;35130:5;35123:13;35116:21;35105:32;;35095:48;;;:::o;35149:77::-;;35215:5;35204:16;;35194:32;;;:::o;35232:76::-;;35297:5;35286:16;;35276:32;;;:::o;35314:89::-;;35391:5;35388:1;35377:20;35366:31;;35356:47;;;:::o;35409:126::-;;35486:42;35479:5;35475:54;35464:65;;35454:81;;;:::o;35541:77::-;;35607:5;35596:16;;35586:32;;;:::o;35624:86::-;;35699:4;35692:5;35688:16;35677:27;;35667:43;;;:::o;35716:105::-;;35792:22;35785:5;35781:34;35770:45;;35760:61;;;:::o;35827:134::-;;35918:37;35949:5;35918:37;:::i;:::-;35905:50;;35895:66;;;:::o;35967:126::-;;36050:37;36081:5;36050:37;:::i;:::-;36037:50;;36027:66;;;:::o;36099:113::-;;36182:24;36200:5;36182:24;:::i;:::-;36169:37;;36159:53;;;:::o;36218:154::-;36302:6;36297:3;36292;36279:30;36364:1;36355:6;36350:3;36346:16;36339:27;36269:103;;;:::o;36378:307::-;36446:1;36456:113;36470:6;36467:1;36464:13;36456:113;;;36555:1;36550:3;36546:11;36540:18;36536:1;36531:3;36527:11;36520:39;36492:2;36489:1;36485:10;36480:15;;36456:113;;;36587:6;36584:1;36581:13;36578:2;;;36667:1;36658:6;36653:3;36649:16;36642:27;36578:2;36427:258;;;;:::o;36691:100::-;;36759:26;36779:5;36759:26;:::i;:::-;36748:37;;36738:53;;;:::o;36797:79::-;;36865:5;36854:16;;36844:32;;;:::o;36882:94::-;;36950:20;36964:5;36950:20;:::i;:::-;36939:31;;36929:47;;;:::o;36982:79::-;;37050:5;37039:16;;37029:32;;;:::o;37067:48::-;37100:9;37121:102;;37213:2;37209:7;37204:2;37197:5;37193:14;37189:28;37179:38;;37169:54;;;:::o;37229:94::-;;37310:5;37306:2;37302:14;37281:35;;37271:52;;;:::o;37329:122::-;37402:24;37420:5;37402:24;:::i;:::-;37395:5;37392:35;37382:2;;37441:1;37438;37431:12;37382:2;37372:79;:::o;37457:116::-;37527:21;37542:5;37527:21;:::i;:::-;37520:5;37517:32;37507:2;;37563:1;37560;37553:12;37507:2;37497:76;:::o;37579:122::-;37652:24;37670:5;37652:24;:::i;:::-;37645:5;37642:35;37632:2;;37691:1;37688;37681:12;37632:2;37622:79;:::o;37707:120::-;37779:23;37796:5;37779:23;:::i;:::-;37772:5;37769:34;37759:2;;37817:1;37814;37807:12;37759:2;37749:78;:::o;37833:116::-;37903:21;37918:5;37903:21;:::i;:::-;37896:5;37893:32;37883:2;;37939:1;37936;37929:12;37883:2;37873:76;:::o;37955:122::-;38028:24;38046:5;38028:24;:::i;:::-;38021:5;38018:35;38008:2;;38067:1;38064;38057:12;38008:2;37998:79;:::o;38083:118::-;38154:22;38170:5;38154:22;:::i;:::-;38147:5;38144:33;38134:2;;38191:1;38188;38181:12;38134:2;38124:77;:::o;38207:120::-;38279:23;38296:5;38279:23;:::i;:::-;38272:5;38269:34;38259:2;;38317:1;38314;38307:12;38259:2;38249:78;:::o
Swarm Source
ipfs://044bf06927f6b50e2252b0668d01ffd00ed540a0f37d6f872c22b18ef95a77e1
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $1 | 7,761.2889 | $7,761.29 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.