ERC-20
Overview
Max Total Supply
29,062.97978 ETF
Holders
42
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
190 ETFValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
ETF
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT import "./Dependencies.sol"; import "./AuthorizedParticipants.sol"; pragma solidity ^0.8.23; contract ETF is ERC20 { uint256 public constant TOKENS_PER_ETH = 10000; uint256 public constant INCEPTION = 1712586600; // 4/8 10:30am EDT (9:30am EST, 14:30pm UTC) uint256 public constant MARKET_OPEN_DURATION = 6 hours + 30 minutes; bool public isDST; AuthorizedParticipants public authorizedParticipants; mapping(uint256 => uint256) public created; mapping(uint256 => uint256) public redeemed; mapping(uint256 => bool) public isMarketHoliday; mapping(uint256 => uint256) public yearToMarketHolidaysDeclared; event Creation(uint256 _tokenId, uint256 _amount); event Redemption(uint256 _tokenId, uint256 _amount); event DeclareDST(bool value); event DeclareMarketHoliday(uint256 indexed year, uint256 day); constructor() ERC20('ETF', 'ETF') { authorizedParticipants = new AuthorizedParticipants(msg.sender); } function nav() public view returns (uint256) { return (address(this).balance) / (totalSupply() / 1 ether); } //// Market Hours function yearsElapsed() public view returns (uint256) { return (block.timestamp - INCEPTION) / 365 days; } function daysElapsed() public view returns (uint256) { uint256 dstAdjustment = isDST ? 1 hours : 0; uint256 timeElapsed = (block.timestamp - INCEPTION) + dstAdjustment; return timeElapsed / 1 days; } function isMarketOpen() public view returns (bool) { uint256 dstAdjustment = isDST ? 1 hours : 0; uint256 timeElapsed = (block.timestamp - INCEPTION) + dstAdjustment; uint256 marketTime = timeElapsed % 1 days; uint256 _daysElapsed = timeElapsed / 1 days; uint8 dayOfWeek = uint8(_daysElapsed % 7); return ( dayOfWeek < 5 && !isMarketHoliday[_daysElapsed] // Monday - Friday & not a market holiday && marketTime < MARKET_OPEN_DURATION // 9:30am - 4:00pm (EST or EDT, depending on DST) ); } function _beforeTokenTransfer(address, address, uint256) internal virtual override { require(isMarketOpen(), 'Can only transfer during market trading hours'); } //// Authorized Participant actions function create(uint256 tokenId, address recipient) external payable { require(msg.sender == authorizedParticipants.ownerOf(tokenId), 'Only Authorized Participants can create tokens'); require(tokenId > 0, 'Time Lord cannot create tokens'); uint256 amountToCreate = msg.value * TOKENS_PER_ETH; _mint(recipient, amountToCreate); created[tokenId] += amountToCreate; authorizedParticipants.metadataUpdate(tokenId); emit Creation(tokenId, amountToCreate); } function redeem(uint256 tokenId, address recipient, uint256 redeemAmount) external { require(msg.sender == authorizedParticipants.ownerOf(tokenId), 'Only Authorized Participants can redeem tokens'); require(tokenId > 0, 'Time Lord cannot redeem tokens'); _burn(msg.sender, redeemAmount); bool sent = payable(recipient).send(redeemAmount / TOKENS_PER_ETH); require(sent); redeemed[tokenId] += redeemAmount; authorizedParticipants.metadataUpdate(tokenId); emit Redemption(tokenId, redeemAmount); } //// Time Lord actions function declareMarketHoliday(uint256 day) external { require(msg.sender == authorizedParticipants.ownerOf(0), 'Only the Time Lord can declare Market Holidays'); require(yearToMarketHolidaysDeclared[yearsElapsed()] < 10, 'The Time Lord can only declare 10 Market Holidays per fiscal year'); require(day >= daysElapsed() && day <= (daysElapsed() + 366), 'The Time Lord can only declare Market Holidays within the fiscal year'); if (!isMarketHoliday[day]) { isMarketHoliday[day] = true; yearToMarketHolidaysDeclared[yearsElapsed()]++; authorizedParticipants.metadataUpdate(0); emit DeclareMarketHoliday(yearsElapsed(), day); } } function declareDST(bool dst) external { require(msg.sender == authorizedParticipants.ownerOf(0), 'Only the Time Lord can declare DST'); isDST = dst; authorizedParticipants.metadataUpdate(0); emit DeclareDST(dst); } }
// SPDX-License-Identifier: MIT import "./Dependencies.sol"; import "./ETF.sol"; pragma solidity ^0.8.23; contract AuthorizedParticipants is ERC721, Ownable { uint256 public constant totalSupply = 7; ETF public etf; TokenURI public tokenURIContract; struct RevokeProposal { uint256 tokenId; address destination; } mapping(uint256 => RevokeProposal) public revokeProposals; event MetadataUpdate(uint256 _tokenId); event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); constructor(address _owner) ERC721('ETF Authorized Participants', 'AP') { etf = ETF(msg.sender); transferOwnership(_owner); tokenURIContract = new TokenURI(msg.sender); for (uint i; i < totalSupply; i++) { _mint(_owner, i); } } function exists(uint256 tokenId) external view returns (bool) { return _exists(tokenId); } function metadataUpdate(uint256 tokenId) external { require(msg.sender == address(etf)); emit MetadataUpdate(tokenId); } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { return TokenURI(tokenURIContract).tokenURI(tokenId); } function setURIContract(address _uriContract) external onlyOwner { tokenURIContract = TokenURI(_uriContract); emit BatchMetadataUpdate(0, totalSupply); } function proposeRevoke(uint256 votingTokenId, uint256 revokedTokenId, address revokeDestination) external { require(votingTokenId != 0, 'Time Lord cannot revoke'); require(revokedTokenId != 0, 'Cannot revoke the Time Lord'); require(ownerOf(votingTokenId) == msg.sender, 'Not authorized to make revoke proposal'); revokeProposals[votingTokenId].tokenId = revokedTokenId; revokeProposals[votingTokenId].destination = revokeDestination; } function revoke(uint256 revokedTokenId, address revokeDestination) external { uint revokeCount; for (uint i = 1; i < totalSupply; i++) { RevokeProposal storage rp = revokeProposals[i]; if ( rp.tokenId != 0 && rp.tokenId == revokedTokenId && rp.destination == revokeDestination ) { revokeCount++; rp.tokenId = 0; rp.destination = address(0); } } require(revokeCount >= totalSupply - 2, 'Not enough votes to revoke AP token'); _transfer(ownerOf(revokedTokenId), revokeDestination, revokedTokenId); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721) returns (bool) { return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId); } } contract TokenURI { using Strings for uint256; ETF public etf; AuthorizedParticipants public ap; string public externalUrl = "https://etf.steviep.xyz"; constructor(address _etf) { etf = ETF(_etf); ap = AuthorizedParticipants(msg.sender); } function tokenURI(uint256 tokenId) public view returns (string memory) { bytes memory encodedSVG = abi.encodePacked( 'data:image/svg+xml;base64,', Base64.encode( tokenId > 0 ? apSVG(tokenId) : timeLordSVG() ) ); string memory attrs = getAttrs(tokenId); string memory name = tokenId > 0 ? string.concat('Authorized Participant ', tokenId.toString()) : 'Time Lord'; string memory description = getDescription(tokenId); bytes memory json = abi.encodePacked( 'data:application/json;utf8,', '{"name": "', name, '",', '"description": "', description, '",', '"image": "', encodedSVG, '",', '"attributes": ', attrs,',', '"external_url": "', externalUrl, '"', '}' ); return string(json); } function setURL(string memory url) external { require(msg.sender == ap.owner(), 'Only AP contract owner can set url'); externalUrl = url; } function getDescription(uint256 tokenId) public pure returns (string memory) { string memory roleText = tokenId > 0 ? 'Authorized Participants have the right (but not the obligation) to create and redeem shares of ETF.' : 'The Time Lord has the sole ability to declare Market Holidays and DST.'; return string.concat( 'ETF seeks to simulate the experience of owning shares of an exchange-traded fund that seeks to reflect, before fees and expenses, the performance of the price of Ethereum. ', roleText ); } function getAttrs(uint256 tokenId) public view returns (string memory) { if (tokenId > 0) { uint256 tokensCreated = (etf.created(tokenId) / 1 ether); uint256 tokensRedeemed = (etf.redeemed(tokenId) / 1 ether); return string.concat( '[', '{"trait_type": "Shares Created", "value": "', tokensCreated.toString(), '"},', '{"trait_type": "Shares Redeemed", "value": "', tokensRedeemed.toString(), '"}', ']' ); } else { return string.concat( '[', '{"trait_type": "Market Holidays Set For Year", "value": "', etf.yearToMarketHolidaysDeclared(etf.yearsElapsed()).toString(), '"},', '{"trait_type": "Is DST", "value": "', etf.isDST() ? 'True' : 'False', '"}', ']' ); } } function timeLordSVG() public view returns (bytes memory) { string memory c1 = etf.isDST() ? '383a3c' : '0078bd'; string memory c2 = etf.isDST() ? '0078bd' : '383a3c'; return abi.encodePacked( '<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">' '<circle cx="250" cy="250" r="250" fill="#', c1, '"></circle>' '<circle cx="250" cy="250" r="230" fill="#', c2, '"></circle>' '<text x="250" y="270" dominant-baseline="middle" text-anchor="middle" fill="#fff" font-size="250" font-family="sans-serif">TL</text>' '</svg>' ); } function apSVG(uint256 tokenId) public pure returns (bytes memory) { uint256 i = tokenId - 1; string[2][6] memory params = [ ['383a3c', 'fff'], ['383a3c', '0078bd'], ['0078bd', 'fff'], ['0078bd', '383a3c'], ['fff', '383a3c'], ['fff', '0078bd'] ]; return abi.encodePacked( '<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">' '<style>' 'text{font-family:monospace;fill:#',params[i][0],';font-size:180px}' 'rect{fill:#',params[i][1],';stroke:#',params[i][0],';stroke-width:35px}' '</style>' '<rect x="0" y="0" width="500" height="500"></rect>' '<text class="fillLight" x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">AP',tokenId.toString(),'</text>' '</svg>' ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } /** * @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; 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"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } // /** // * @dev Performs a Solidity function call using a low level `call`. A // * plain `call` is an unsafe replacement for a function call: use this // * function instead. // * // * If `target` reverts with a revert reason, it is bubbled up by this // * function (like regular Solidity function calls). // * // * Returns the raw returned data. To convert to the expected return value, // * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. // * // * Requirements: // * // * - `target` must be a contract. // * - calling `target` with `data` must not revert. // * // * _Available since v3.1._ // */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } // /** // * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with // * `errorMessage` as a fallback revert reason when `target` reverts. // * // * _Available since v3.1._ // */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } // /** // * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], // * but also transferring `value` wei to `target`. // * // * Requirements: // * // * - the calling contract must have an ETH balance of at least `value`. // * - the called Solidity function must be `payable`. // * // * _Available since v3.1._ // */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } // * // * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but // * with `errorMessage` as a fallback revert reason when `target` reverts. // * // * _Available since v3.1._ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } // /** // * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], // * but performing a static call. // * // * _Available since v3.3._ // */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } // /** // * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], // * but performing a static call. // * // * _Available since v3.3._ // */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } // /** // * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], // * but performing a delegate call. // * // * _Available since v3.4._ // */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } // /** // * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], // * but performing a delegate call. // * // * _Available since v3.4._ // */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } // /** // * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the // * revert reason using the provided one. // * // * _Available since v4.3._ // */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } // Don't need these /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } /// [MIT License] /// @title Base64 /// @notice Provides a function for encoding some bytes in base64 /// @author Brecht Devos <[email protected]> library Base64 { bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /// @notice Encodes some bytes to the base64 representation function encode(bytes memory data) internal pure returns (string memory) { uint256 len = data.length; if (len == 0) return ""; // multiply by 4/3 rounded up uint256 encodedLen = 4 * ((len + 2) / 3); // Add some extra buffer at the end bytes memory result = new bytes(encodedLen + 32); bytes memory table = TABLE; assembly { let tablePtr := add(table, 1) let resultPtr := add(result, 32) for { let i := 0 } lt(i, len) { } { i := add(i, 3) let input := and(mload(add(data, i)), 0xffffff) let out := mload(add(tablePtr, and(shr(18, input), 0x3F))) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)) out := shl(224, out) mstore(resultPtr, out) resultPtr := add(resultPtr, 4) } switch mod(len, 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } mstore(result, encodedLen) } return string(result); } } /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); } /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @dev 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; } /** * @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); } /** * @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); } /// @title IOptimismMintableERC20 /// @notice This interface is available on the OptimismMintableERC20 contract. /// We declare it as a separate interface so that it can be used in /// custom implementations of OptimismMintableERC20. interface IOptimismMintableERC20 is IERC165 { function remoteToken() external view returns (address); function bridge() external returns (address); function mint(address _to, uint256 _amount) external; function burn(address _from, uint256 _amount) external; } /// @custom:legacy /// @title ILegacyMintableERC20 /// @notice This interface was available on the legacy L2StandardERC20 contract. /// It remains available on the OptimismMintableERC20 contract for /// backwards compatibility. interface ILegacyMintableERC20 is IERC165 { function l1Token() external view returns (address); function mint(address _to, uint256 _amount) external; function burn(address _from, uint256 _amount) external; } /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } /** * @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() { _setOwner(_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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} } /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { 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 _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @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"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } /** * @title ERC721 Burnable Token * @dev ERC721 Token that can be burned (destroyed). */ abstract contract ERC721Burnable is Context, ERC721 { /** * @dev Burns `tokenId`. See {ERC721-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _burn(tokenId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Creation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"DeclareDST","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"year","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"day","type":"uint256"}],"name":"DeclareMarketHoliday","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Redemption","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"INCEPTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MARKET_OPEN_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKENS_PER_ETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authorizedParticipants","outputs":[{"internalType":"contract AuthorizedParticipants","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"create","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"created","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daysElapsed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"dst","type":"bool"}],"name":"declareDST","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"day","type":"uint256"}],"name":"declareMarketHoliday","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isDST","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isMarketHoliday","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMarketOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nav","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"redeemAmount","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"redeemed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"yearToMarketHolidaysDeclared","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yearsElapsed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801562000010575f80fd5b506040518060400160405280600381526020017f45544600000000000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f455446000000000000000000000000000000000000000000000000000000000081525081600390816200008e919062000391565b508060049081620000a0919062000391565b50505033604051620000b2906200011f565b620000be9190620004b8565b604051809103905ff080158015620000d8573d5f803e3d5ffd5b50600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620004d3565b616d54806200346f83390190565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620001a957607f821691505b602082108103620001bf57620001be62000164565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620002237fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620001e6565b6200022f8683620001e6565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000279620002736200026d8462000247565b62000250565b62000247565b9050919050565b5f819050919050565b620002948362000259565b620002ac620002a38262000280565b848454620001f2565b825550505050565b5f90565b620002c2620002b4565b620002cf81848462000289565b505050565b5b81811015620002f657620002ea5f82620002b8565b600181019050620002d5565b5050565b601f82111562000345576200030f81620001c5565b6200031a84620001d7565b810160208510156200032a578190505b620003426200033985620001d7565b830182620002d4565b50505b505050565b5f82821c905092915050565b5f620003675f19846008026200034a565b1980831691505092915050565b5f62000381838362000356565b9150826002028217905092915050565b6200039c826200012d565b67ffffffffffffffff811115620003b857620003b762000137565b5b620003c4825462000191565b620003d1828285620002fa565b5f60209050601f83116001811462000407575f8415620003f2578287015190505b620003fe858262000374565b8655506200046d565b601f1984166200041786620001c5565b5f5b82811015620004405784890151825560018201915060208501945060208101905062000419565b868310156200046057848901516200045c601f89168262000356565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620004a08262000475565b9050919050565b620004b28162000494565b82525050565b5f602082019050620004cd5f830184620004a7565b92915050565b612f8e80620004e15f395ff3fe6080604052600436106101b6575f3560e01c806382cb6b72116100eb578063bc6e660411610089578063d4ce85f311610063578063d4ce85f31461065a578063d878016114610684578063dd62ed3e146106ac578063f01fe692146106e8576101b6565b8063bc6e6604146105dc578063c1590cd714610606578063c1c407ac14610630576101b6565b80639c2f5661116100c55780639c2f5661146105125780639d55cb581461053a578063a457c2d714610564578063a9059cbb146105a0576101b6565b806382cb6b721461048257806385e5a46b146104be57806395d89b41146104e8576101b6565b8063395093511161015857806361873b441161013257806361873b44146103a457806370a08231146103e05780637ed0f1c11461041c57806380477a4c14610458576101b6565b806339509351146103025780633b4d0bd21461033e5780635b603e4114610368576101b6565b806323b872dd1161019457806323b872dd1461024a57806324f5ffdd14610286578063313ce567146102ae5780633508e27a146102d8576101b6565b806306fdde03146101ba578063095ea7b3146101e457806318160ddd14610220575b5f80fd5b3480156101c5575f80fd5b506101ce610704565b6040516101db9190611ea4565b60405180910390f35b3480156101ef575f80fd5b5061020a60048036038101906102059190611f55565b610794565b6040516102179190611fad565b60405180910390f35b34801561022b575f80fd5b506102346107b6565b6040516102419190611fd5565b60405180910390f35b348015610255575f80fd5b50610270600480360381019061026b9190611fee565b6107bf565b60405161027d9190611fad565b60405180910390f35b348015610291575f80fd5b506102ac60048036038101906102a7919061203e565b6107ed565b005b3480156102b9575f80fd5b506102c2610afc565b6040516102cf9190612084565b60405180910390f35b3480156102e3575f80fd5b506102ec610b04565b6040516102f99190611fd5565b60405180910390f35b34801561030d575f80fd5b5061032860048036038101906103239190611f55565b610b0a565b6040516103359190611fad565b60405180910390f35b348015610349575f80fd5b50610352610b40565b60405161035f9190611fad565b60405180910390f35b348015610373575f80fd5b5061038e6004803603810190610389919061203e565b610b52565b60405161039b9190611fd5565b60405180910390f35b3480156103af575f80fd5b506103ca60048036038101906103c5919061203e565b610b67565b6040516103d79190611fad565b60405180910390f35b3480156103eb575f80fd5b506104066004803603810190610401919061209d565b610b84565b6040516104139190611fd5565b60405180910390f35b348015610427575f80fd5b50610442600480360381019061043d919061203e565b610bc9565b60405161044f9190611fd5565b60405180910390f35b348015610463575f80fd5b5061046c610bde565b6040516104799190611fd5565b60405180910390f35b34801561048d575f80fd5b506104a860048036038101906104a3919061203e565b610c37565b6040516104b59190611fd5565b60405180910390f35b3480156104c9575f80fd5b506104d2610c4c565b6040516104df9190611fd5565b60405180910390f35b3480156104f3575f80fd5b506104fc610c71565b6040516105099190611ea4565b60405180910390f35b34801561051d575f80fd5b50610538600480360381019061053391906120f2565b610d01565b005b348015610545575f80fd5b5061054e610ee3565b60405161055b9190612178565b60405180910390f35b34801561056f575f80fd5b5061058a60048036038101906105859190611f55565b610f09565b6040516105979190611fad565b60405180910390f35b3480156105ab575f80fd5b506105c660048036038101906105c19190611f55565b610f7e565b6040516105d39190611fad565b60405180910390f35b3480156105e7575f80fd5b506105f0610fa0565b6040516105fd9190611fd5565b60405180910390f35b348015610611575f80fd5b5061061a610fa6565b6040516106279190611fd5565b60405180910390f35b34801561063b575f80fd5b50610644610fd2565b6040516106519190611fd5565b60405180910390f35b348015610665575f80fd5b5061066e610fda565b60405161067b9190611fad565b60405180910390f35b34801561068f575f80fd5b506106aa60048036038101906106a59190612191565b611096565b005b3480156106b7575f80fd5b506106d260048036038101906106cd91906121e1565b611324565b6040516106df9190611fd5565b60405180910390f35b61070260048036038101906106fd919061221f565b6113a6565b005b6060600380546107139061228a565b80601f016020809104026020016040519081016040528092919081815260200182805461073f9061228a565b801561078a5780601f106107615761010080835404028352916020019161078a565b820191905f5260205f20905b81548152906001019060200180831161076d57829003601f168201915b5050505050905090565b5f8061079e6115f7565b90506107ab8185856115fe565b600191505092915050565b5f600254905090565b5f806107c96115f7565b90506107d68582856117c1565b6107e185858561184c565b60019150509392505050565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e5f6040518263ffffffff1660e01b815260040161084891906122f3565b602060405180830381865afa158015610863573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108879190612320565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108eb906123bb565b60405180910390fd5b600a60095f610901610c4c565b81526020019081526020015f20541061094f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109469061246f565b60405180910390fd5b610957610bde565b811015801561097a575061016e61096c610bde565b61097691906124ba565b8111155b6109b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109b090612583565b60405180910390fd5b60085f8281526020019081526020015f205f9054906101000a900460ff16610af957600160085f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555060095f610a0f610c4c565b81526020019081526020015f205f815480929190610a2c906125a1565b9190505550600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a1c34fb5f6040518263ffffffff1660e01b8152600401610a8c91906122f3565b5f604051808303815f87803b158015610aa3575f80fd5b505af1158015610ab5573d5f803e3d5ffd5b50505050610ac1610c4c565b7f59ad40d521feb27052c7e7e3741f839354d35da2bd0fc555bd87d097635b906582604051610af09190611fd5565b60405180910390a25b50565b5f6012905090565b615b6881565b5f80610b146115f7565b9050610b35818585610b268589611324565b610b3091906124ba565b6115fe565b600191505092915050565b60055f9054906101000a900460ff1681565b6009602052805f5260405f205f915090505481565b6008602052805f5260405f205f915054906101000a900460ff1681565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6007602052805f5260405f205f915090505481565b5f8060055f9054906101000a900460ff16610bf9575f610bfd565b610e105b61ffff1690505f81636613ff6842610c1591906125e8565b610c1f91906124ba565b90506201518081610c309190612648565b9250505090565b6006602052805f5260405f205f915090505481565b5f6301e13380636613ff6842610c6291906125e8565b610c6c9190612648565b905090565b606060048054610c809061228a565b80601f0160208091040260200160405190810160405280929190818152602001828054610cac9061228a565b8015610cf75780601f10610cce57610100808354040283529160200191610cf7565b820191905f5260205f20905b815481529060010190602001808311610cda57829003601f168201915b5050505050905090565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e5f6040518263ffffffff1660e01b8152600401610d5c91906122f3565b602060405180830381865afa158015610d77573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d9b9190612320565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dff906126e8565b60405180910390fd5b8060055f6101000a81548160ff021916908315150217905550600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a1c34fb5f6040518263ffffffff1660e01b8152600401610e7c91906122f3565b5f604051808303815f87803b158015610e93575f80fd5b505af1158015610ea5573d5f803e3d5ffd5b505050507fc73ba96388f9e70004b21ddf94e0198df57b66950d133faaa024224e87a9191c81604051610ed89190611fad565b60405180910390a150565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f80610f136115f7565b90505f610f208286611324565b905083811015610f65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5c90612776565b60405180910390fd5b610f7282868684036115fe565b60019250505092915050565b5f80610f886115f7565b9050610f9581858561184c565b600191505092915050565b61271081565b5f670de0b6b3a7640000610fb86107b6565b610fc29190612648565b47610fcd9190612648565b905090565b636613ff6881565b5f8060055f9054906101000a900460ff16610ff5575f610ff9565b610e105b61ffff1690505f81636613ff684261101191906125e8565b61101b91906124ba565b90505f620151808261102d9190612794565b90505f620151808361103f9190612648565b90505f60078261104f9190612794565b905060058160ff1610801561107f575060085f8381526020019081526020015f205f9054906101000a900460ff16155b801561108c5750615b6883105b9550505050505090565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016110f19190611fd5565b602060405180830381865afa15801561110c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111309190612320565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461119d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119490612834565b60405180910390fd5b5f83116111df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d69061289c565b60405180910390fd5b6111e93382611ab8565b5f8273ffffffffffffffffffffffffffffffffffffffff166108fc612710846112129190612648565b90811502906040515f60405180830381858888f19350505050905080611236575f80fd5b8160075f8681526020019081526020015f205f82825461125691906124ba565b92505081905550600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a1c34fb856040518263ffffffff1660e01b81526004016112b89190611fd5565b5f604051808303815f87803b1580156112cf575f80fd5b505af11580156112e1573d5f803e3d5ffd5b505050507fba7975764e321f07896c9c9852213d675ea0ab36b67e22a7e6d762b0fddd30d984836040516113169291906128ba565b60405180910390a150505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004016114019190611fd5565b602060405180830381865afa15801561141c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114409190612320565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a490612951565b60405180910390fd5b5f82116114ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e6906129b9565b60405180910390fd5b5f612710346114fe91906129d7565b905061150a8282611c7b565b8060065f8581526020019081526020015f205f82825461152a91906124ba565b92505081905550600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a1c34fb846040518263ffffffff1660e01b815260040161158c9190611fd5565b5f604051808303815f87803b1580156115a3575f80fd5b505af11580156115b5573d5f803e3d5ffd5b505050507f7e9a979db69ea4a9dfb969aa39223836ca1b379955de49444c5a4cd2f9e7dbfe83826040516115ea9291906128ba565b60405180910390a1505050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361166c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166390612a88565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d190612b16565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516117b49190611fd5565b60405180910390a3505050565b5f6117cc8484611324565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146118465781811015611838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182f90612b7e565b60405180910390fd5b61184584848484036115fe565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b190612c0c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611928576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191f90612c9a565b60405180910390fd5b611933838383611dc9565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156119b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ad90612d28565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550815f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611a9f9190611fd5565b60405180910390a3611ab2848484611e15565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1d90612db6565b60405180910390fd5b611b31825f83611dc9565b5f805f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bab90612e44565b60405180910390fd5b8181035f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508160025f82825403925050819055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c639190611fd5565b60405180910390a3611c76835f84611e15565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce090612eac565b60405180910390fd5b611cf45f8383611dc9565b8060025f828254611d0591906124ba565b92505081905550805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508173ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611db29190611fd5565b60405180910390a3611dc55f8383611e15565b5050565b611dd1610fda565b611e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0790612f3a565b60405180910390fd5b505050565b505050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611e51578082015181840152602081019050611e36565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611e7682611e1a565b611e808185611e24565b9350611e90818560208601611e34565b611e9981611e5c565b840191505092915050565b5f6020820190508181035f830152611ebc8184611e6c565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611ef182611ec8565b9050919050565b611f0181611ee7565b8114611f0b575f80fd5b50565b5f81359050611f1c81611ef8565b92915050565b5f819050919050565b611f3481611f22565b8114611f3e575f80fd5b50565b5f81359050611f4f81611f2b565b92915050565b5f8060408385031215611f6b57611f6a611ec4565b5b5f611f7885828601611f0e565b9250506020611f8985828601611f41565b9150509250929050565b5f8115159050919050565b611fa781611f93565b82525050565b5f602082019050611fc05f830184611f9e565b92915050565b611fcf81611f22565b82525050565b5f602082019050611fe85f830184611fc6565b92915050565b5f805f6060848603121561200557612004611ec4565b5b5f61201286828701611f0e565b935050602061202386828701611f0e565b925050604061203486828701611f41565b9150509250925092565b5f6020828403121561205357612052611ec4565b5b5f61206084828501611f41565b91505092915050565b5f60ff82169050919050565b61207e81612069565b82525050565b5f6020820190506120975f830184612075565b92915050565b5f602082840312156120b2576120b1611ec4565b5b5f6120bf84828501611f0e565b91505092915050565b6120d181611f93565b81146120db575f80fd5b50565b5f813590506120ec816120c8565b92915050565b5f6020828403121561210757612106611ec4565b5b5f612114848285016120de565b91505092915050565b5f819050919050565b5f61214061213b61213684611ec8565b61211d565b611ec8565b9050919050565b5f61215182612126565b9050919050565b5f61216282612147565b9050919050565b61217281612158565b82525050565b5f60208201905061218b5f830184612169565b92915050565b5f805f606084860312156121a8576121a7611ec4565b5b5f6121b586828701611f41565b93505060206121c686828701611f0e565b92505060406121d786828701611f41565b9150509250925092565b5f80604083850312156121f7576121f6611ec4565b5b5f61220485828601611f0e565b925050602061221585828601611f0e565b9150509250929050565b5f806040838503121561223557612234611ec4565b5b5f61224285828601611f41565b925050602061225385828601611f0e565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806122a157607f821691505b6020821081036122b4576122b361225d565b5b50919050565b5f819050919050565b5f6122dd6122d86122d3846122ba565b61211d565b611f22565b9050919050565b6122ed816122c3565b82525050565b5f6020820190506123065f8301846122e4565b92915050565b5f8151905061231a81611ef8565b92915050565b5f6020828403121561233557612334611ec4565b5b5f6123428482850161230c565b91505092915050565b7f4f6e6c79207468652054696d65204c6f72642063616e206465636c617265204d5f8201527f61726b657420486f6c6964617973000000000000000000000000000000000000602082015250565b5f6123a5602e83611e24565b91506123b08261234b565b604082019050919050565b5f6020820190508181035f8301526123d281612399565b9050919050565b7f5468652054696d65204c6f72642063616e206f6e6c79206465636c61726520315f8201527f30204d61726b657420486f6c6964617973207065722066697363616c2079656160208201527f7200000000000000000000000000000000000000000000000000000000000000604082015250565b5f612459604183611e24565b9150612464826123d9565b606082019050919050565b5f6020820190508181035f8301526124868161244d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6124c482611f22565b91506124cf83611f22565b92508282019050808211156124e7576124e661248d565b5b92915050565b7f5468652054696d65204c6f72642063616e206f6e6c79206465636c617265204d5f8201527f61726b657420486f6c69646179732077697468696e207468652066697363616c60208201527f2079656172000000000000000000000000000000000000000000000000000000604082015250565b5f61256d604583611e24565b9150612578826124ed565b606082019050919050565b5f6020820190508181035f83015261259a81612561565b9050919050565b5f6125ab82611f22565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036125dd576125dc61248d565b5b600182019050919050565b5f6125f282611f22565b91506125fd83611f22565b92508282039050818111156126155761261461248d565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61265282611f22565b915061265d83611f22565b92508261266d5761266c61261b565b5b828204905092915050565b7f4f6e6c79207468652054696d65204c6f72642063616e206465636c61726520445f8201527f5354000000000000000000000000000000000000000000000000000000000000602082015250565b5f6126d2602283611e24565b91506126dd82612678565b604082019050919050565b5f6020820190508181035f8301526126ff816126c6565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f775f8201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b5f612760602583611e24565b915061276b82612706565b604082019050919050565b5f6020820190508181035f83015261278d81612754565b9050919050565b5f61279e82611f22565b91506127a983611f22565b9250826127b9576127b861261b565b5b828206905092915050565b7f4f6e6c7920417574686f72697a6564205061727469636970616e74732063616e5f8201527f2072656465656d20746f6b656e73000000000000000000000000000000000000602082015250565b5f61281e602e83611e24565b9150612829826127c4565b604082019050919050565b5f6020820190508181035f83015261284b81612812565b9050919050565b7f54696d65204c6f72642063616e6e6f742072656465656d20746f6b656e7300005f82015250565b5f612886601e83611e24565b915061289182612852565b602082019050919050565b5f6020820190508181035f8301526128b38161287a565b9050919050565b5f6040820190506128cd5f830185611fc6565b6128da6020830184611fc6565b9392505050565b7f4f6e6c7920417574686f72697a6564205061727469636970616e74732063616e5f8201527f2063726561746520746f6b656e73000000000000000000000000000000000000602082015250565b5f61293b602e83611e24565b9150612946826128e1565b604082019050919050565b5f6020820190508181035f8301526129688161292f565b9050919050565b7f54696d65204c6f72642063616e6e6f742063726561746520746f6b656e7300005f82015250565b5f6129a3601e83611e24565b91506129ae8261296f565b602082019050919050565b5f6020820190508181035f8301526129d081612997565b9050919050565b5f6129e182611f22565b91506129ec83611f22565b92508282026129fa81611f22565b91508282048414831517612a1157612a1061248d565b5b5092915050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f612a72602483611e24565b9150612a7d82612a18565b604082019050919050565b5f6020820190508181035f830152612a9f81612a66565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f2061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f612b00602283611e24565b9150612b0b82612aa6565b604082019050919050565b5f6020820190508181035f830152612b2d81612af4565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000005f82015250565b5f612b68601d83611e24565b9150612b7382612b34565b602082019050919050565b5f6020820190508181035f830152612b9581612b5c565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f2061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f612bf6602583611e24565b9150612c0182612b9c565b604082019050919050565b5f6020820190508181035f830152612c2381612bea565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f612c84602383611e24565b9150612c8f82612c2a565b604082019050919050565b5f6020820190508181035f830152612cb181612c78565b9050919050565b7f45524332303a207472616e7366657220616d6f756e74206578636565647320625f8201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b5f612d12602683611e24565b9150612d1d82612cb8565b604082019050919050565b5f6020820190508181035f830152612d3f81612d06565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f612da0602183611e24565b9150612dab82612d46565b604082019050919050565b5f6020820190508181035f830152612dcd81612d94565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e5f8201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b5f612e2e602283611e24565b9150612e3982612dd4565b604082019050919050565b5f6020820190508181035f830152612e5b81612e22565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f2061646472657373005f82015250565b5f612e96601f83611e24565b9150612ea182612e62565b602082019050919050565b5f6020820190508181035f830152612ec381612e8a565b9050919050565b7f43616e206f6e6c79207472616e7366657220647572696e67206d61726b6574205f8201527f74726164696e6720686f75727300000000000000000000000000000000000000602082015250565b5f612f24602d83611e24565b9150612f2f82612eca565b604082019050919050565b5f6020820190508181035f830152612f5181612f18565b905091905056fea2646970667358221220589505703d45bf636cd888910ca759e61683f1bf8890829c3998bcf44b9193ce64736f6c63430008170033608060405234801562000010575f80fd5b5060405162006d5438038062006d548339818101604052810190620000369190620006a3565b6040518060400160405280601b81526020017f45544620417574686f72697a6564205061727469636970616e747300000000008152506040518060400160405280600281526020017f4150000000000000000000000000000000000000000000000000000000000000815250815f9081620000b2919062000937565b508060019081620000c4919062000937565b505050620000e7620000db620001e160201b60201c565b620001e860201b60201c565b3360075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506200013881620002ab60201b60201c565b33604051620001479062000630565b62000153919062000a2c565b604051809103905ff0801580156200016d573d5f803e3d5ffd5b5060085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f5b6007811015620001d957620001cb8282620003bf60201b60201c565b8080600101915050620001af565b505062000c9c565b5f33905090565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620002bb620001e160201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620002e16200059b60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16146200033a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003319062000aa5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620003ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003a29062000b39565b60405180910390fd5b620003bc81620001e860201b60201c565b50565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000430576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004279062000ba7565b60405180910390fd5b6200044181620005c360201b60201c565b1562000484576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200047b9062000c15565b60405180910390fd5b620004975f83836200062b60201b60201c565b600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254620004e6919062000c62565b925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f8073ffffffffffffffffffffffffffffffffffffffff1660025f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b505050565b6131a18062003bb383390190565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200066d8262000642565b9050919050565b6200067f8162000661565b81146200068a575f80fd5b50565b5f815190506200069d8162000674565b92915050565b5f60208284031215620006bb57620006ba6200063e565b5b5f620006ca848285016200068d565b91505092915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200074f57607f821691505b6020821081036200076557620007646200070a565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620007c97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200078c565b620007d586836200078c565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200081f620008196200081384620007ed565b620007f6565b620007ed565b9050919050565b5f819050919050565b6200083a83620007ff565b62000852620008498262000826565b84845462000798565b825550505050565b5f90565b620008686200085a565b620008758184846200082f565b505050565b5b818110156200089c57620008905f826200085e565b6001810190506200087b565b5050565b601f821115620008eb57620008b5816200076b565b620008c0846200077d565b81016020851015620008d0578190505b620008e8620008df856200077d565b8301826200087a565b50505b505050565b5f82821c905092915050565b5f6200090d5f1984600802620008f0565b1980831691505092915050565b5f620009278383620008fc565b9150826002028217905092915050565b6200094282620006d3565b67ffffffffffffffff8111156200095e576200095d620006dd565b5b6200096a825462000737565b62000977828285620008a0565b5f60209050601f831160018114620009ad575f841562000998578287015190505b620009a485826200091a565b86555062000a13565b601f198416620009bd866200076b565b5f5b82811015620009e657848901518255600182019150602085019450602081019050620009bf565b8683101562000a06578489015162000a02601f891682620008fc565b8355505b6001600288020188555050505b505050505050565b62000a268162000661565b82525050565b5f60208201905062000a415f83018462000a1b565b92915050565b5f82825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f62000a8d60208362000a47565b915062000a9a8262000a57565b602082019050919050565b5f6020820190508181035f83015262000abe8162000a7f565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f62000b2160268362000a47565b915062000b2e8262000ac5565b604082019050919050565b5f6020820190508181035f83015262000b528162000b13565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f20616464726573735f82015250565b5f62000b8f60208362000a47565b915062000b9c8262000b59565b602082019050919050565b5f6020820190508181035f83015262000bc08162000b81565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e746564000000005f82015250565b5f62000bfd601c8362000a47565b915062000c0a8262000bc7565b602082019050919050565b5f6020820190508181035f83015262000c2e8162000bef565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f62000c6e82620007ed565b915062000c7b83620007ed565b925082820190508082111562000c965762000c9562000c35565b5b92915050565b612f098062000caa5f395ff3fe608060405234801561000f575f80fd5b5060043610610171575f3560e01c806370a08231116100dc578063b88d4fde11610095578063c87b56dd1161006f578063c87b56dd14610434578063e5c4054514610464578063e985e9c514610480578063f2fde38b146104b057610171565b8063b88d4fde146103c9578063bc7ddd95146103e5578063c60e60c91461040357610171565b806370a082311461031b578063715018a61461034b5780638da5cb5b1461035557806395d89b4114610373578063a22cb46514610391578063a84816ea146103ad57610171565b806323b872dd1161012e57806323b872dd1461024957806342842e0e146102655780634f558e79146102815780636352211e146102b1578063698f87be146102e15780636a1c34fb146102ff57610171565b806301ffc9a71461017557806306fdde03146101a5578063081812fc146101c3578063095ea7b3146101f357806318160ddd1461020f57806320d154da1461022d575b5f80fd5b61018f600480360381019061018a9190611c29565b6104cc565b60405161019c9190611c6e565b60405180910390f35b6101ad61052c565b6040516101ba9190611d11565b60405180910390f35b6101dd60048036038101906101d89190611d64565b6105bb565b6040516101ea9190611dce565b60405180910390f35b61020d60048036038101906102089190611e11565b61063c565b005b610217610752565b6040516102249190611e5e565b60405180910390f35b61024760048036038101906102429190611e77565b610757565b005b610263600480360381019061025e9190611eb5565b6108bf565b005b61027f600480360381019061027a9190611eb5565b61091f565b005b61029b60048036038101906102969190611d64565b61093e565b6040516102a89190611c6e565b60405180910390f35b6102cb60048036038101906102c69190611d64565b61094f565b6040516102d89190611dce565b60405180910390f35b6102e96109fb565b6040516102f69190611f60565b60405180910390f35b61031960048036038101906103149190611d64565b610a20565b005b61033560048036038101906103309190611f79565b610ab2565b6040516103429190611e5e565b60405180910390f35b610353610b66565b005b61035d610bed565b60405161036a9190611dce565b60405180910390f35b61037b610c15565b6040516103889190611d11565b60405180910390f35b6103ab60048036038101906103a69190611fce565b610ca5565b005b6103c760048036038101906103c2919061200c565b610e20565b005b6103e360048036038101906103de9190612188565b610f89565b005b6103ed610feb565b6040516103fa9190612228565b60405180910390f35b61041d60048036038101906104189190611d64565b611010565b60405161042b929190612241565b60405180910390f35b61044e60048036038101906104499190611d64565b61104f565b60405161045b9190611d11565b60405180910390f35b61047e60048036038101906104799190611f79565b6110f4565b005b61049a60048036038101906104959190612268565b6111ed565b6040516104a79190611c6e565b60405180910390f35b6104ca60048036038101906104c59190611f79565b61127b565b005b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610525575061052482611371565b5b9050919050565b60605f805461053a906122d3565b80601f0160208091040260200160405190810160405280929190818152602001828054610566906122d3565b80156105b15780601f10610588576101008083540402835291602001916105b1565b820191905f5260205f20905b81548152906001019060200180831161059457829003601f168201915b5050505050905090565b5f6105c582611452565b610604576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105fb90612373565b60405180910390fd5b60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f6106468261094f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036106b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ad90612401565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166106d56114ba565b73ffffffffffffffffffffffffffffffffffffffff1614806107045750610703816106fe6114ba565b6111ed565b5b610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073a9061248f565b60405180910390fd5b61074d83836114c1565b505050565b600781565b5f80600190505b6007811015610856575f60095f8381526020019081526020015f2090505f815f015414158015610790575084815f0154145b80156107ea57508373ffffffffffffffffffffffffffffffffffffffff16816001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156108485782806107fa906124da565b9350505f815f01819055505f816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50808060010191505061075e565b50600260076108659190612521565b8110156108a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161089e906125c4565b60405180910390fd5b6108ba6108b38461094f565b8385611577565b505050565b6108d06108ca6114ba565b826117c7565b61090f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090690612652565b60405180910390fd5b61091a838383611577565b505050565b61093983838360405180602001604052805f815250610f89565b505050565b5f61094882611452565b9050919050565b5f8060025f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e9906126e0565b60405180910390fd5b80915050919050565b60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a78575f80fd5b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce781604051610aa79190611e5e565b60405180910390a150565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b189061276e565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610b6e6114ba565b73ffffffffffffffffffffffffffffffffffffffff16610b8c610bed565b73ffffffffffffffffffffffffffffffffffffffff1614610be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd9906127d6565b60405180910390fd5b610beb5f6118a3565b565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610c24906122d3565b80601f0160208091040260200160405190810160405280929190818152602001828054610c50906122d3565b8015610c9b5780601f10610c7257610100808354040283529160200191610c9b565b820191905f5260205f20905b815481529060010190602001808311610c7e57829003601f168201915b5050505050905090565b610cad6114ba565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d119061283e565b60405180910390fd5b8060055f610d266114ba565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610dcf6114ba565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610e149190611c6e565b60405180910390a35050565b5f8303610e62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e59906128a6565b60405180910390fd5b5f8203610ea4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9b9061290e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16610ec48461094f565b73ffffffffffffffffffffffffffffffffffffffff1614610f1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f119061299c565b60405180910390fd5b8160095f8581526020019081526020015f205f01819055508060095f8581526020019081526020015f206001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b610f9a610f946114ba565b836117c7565b610fd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd090612652565b60405180910390fd5b610fe584848484611966565b50505050565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6009602052805f5260405f205f91509050805f015490806001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082565b606060085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c87b56dd836040518263ffffffff1660e01b81526004016110ab9190611e5e565b5f60405180830381865afa1580156110c5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110ed9190612a58565b9050919050565b6110fc6114ba565b73ffffffffffffffffffffffffffffffffffffffff1661111a610bed565b73ffffffffffffffffffffffffffffffffffffffff1614611170576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611167906127d6565b60405180910390fd5b8060085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c5f60076040516111e2929190612ad8565b60405180910390a150565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6112836114ba565b73ffffffffffffffffffffffffffffffffffffffff166112a1610bed565b73ffffffffffffffffffffffffffffffffffffffff16146112f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ee906127d6565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611365576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135c90612b6f565b60405180910390fd5b61136e816118a3565b50565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061143b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061144b575061144a826119c2565b5b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff1660025f8481526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b5f33905090565b8160045f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166115318361094f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b8273ffffffffffffffffffffffffffffffffffffffff166115978261094f565b73ffffffffffffffffffffffffffffffffffffffff16146115ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115e490612bfd565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165290612c8b565b60405180910390fd5b611666838383611a2b565b6116705f826114c1565b600160035f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546116bd9190612521565b92505081905550600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546117119190612ca9565b925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b5f6117d182611452565b611810576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180790612d4c565b60405180910390fd5b5f61181a8361094f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061188957508373ffffffffffffffffffffffffffffffffffffffff16611871846105bb565b73ffffffffffffffffffffffffffffffffffffffff16145b8061189a575061189981856111ed565b5b91505092915050565b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611971848484611577565b61197d84848484611a30565b6119bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b390612dda565b60405180910390fd5b50505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b505050565b5f611a508473ffffffffffffffffffffffffffffffffffffffff16611bb2565b15611ba5578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611a796114ba565b8786866040518563ffffffff1660e01b8152600401611a9b9493929190612e4a565b6020604051808303815f875af1925050508015611ad657506040513d601f19601f82011682018060405250810190611ad39190612ea8565b60015b611b55573d805f8114611b04576040519150601f19603f3d011682016040523d82523d5f602084013e611b09565b606091505b505f815103611b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4490612dda565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611baa565b600190505b949350505050565b5f80823b90505f8111915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611c0881611bd4565b8114611c12575f80fd5b50565b5f81359050611c2381611bff565b92915050565b5f60208284031215611c3e57611c3d611bcc565b5b5f611c4b84828501611c15565b91505092915050565b5f8115159050919050565b611c6881611c54565b82525050565b5f602082019050611c815f830184611c5f565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611cbe578082015181840152602081019050611ca3565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611ce382611c87565b611ced8185611c91565b9350611cfd818560208601611ca1565b611d0681611cc9565b840191505092915050565b5f6020820190508181035f830152611d298184611cd9565b905092915050565b5f819050919050565b611d4381611d31565b8114611d4d575f80fd5b50565b5f81359050611d5e81611d3a565b92915050565b5f60208284031215611d7957611d78611bcc565b5b5f611d8684828501611d50565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611db882611d8f565b9050919050565b611dc881611dae565b82525050565b5f602082019050611de15f830184611dbf565b92915050565b611df081611dae565b8114611dfa575f80fd5b50565b5f81359050611e0b81611de7565b92915050565b5f8060408385031215611e2757611e26611bcc565b5b5f611e3485828601611dfd565b9250506020611e4585828601611d50565b9150509250929050565b611e5881611d31565b82525050565b5f602082019050611e715f830184611e4f565b92915050565b5f8060408385031215611e8d57611e8c611bcc565b5b5f611e9a85828601611d50565b9250506020611eab85828601611dfd565b9150509250929050565b5f805f60608486031215611ecc57611ecb611bcc565b5b5f611ed986828701611dfd565b9350506020611eea86828701611dfd565b9250506040611efb86828701611d50565b9150509250925092565b5f819050919050565b5f611f28611f23611f1e84611d8f565b611f05565b611d8f565b9050919050565b5f611f3982611f0e565b9050919050565b5f611f4a82611f2f565b9050919050565b611f5a81611f40565b82525050565b5f602082019050611f735f830184611f51565b92915050565b5f60208284031215611f8e57611f8d611bcc565b5b5f611f9b84828501611dfd565b91505092915050565b611fad81611c54565b8114611fb7575f80fd5b50565b5f81359050611fc881611fa4565b92915050565b5f8060408385031215611fe457611fe3611bcc565b5b5f611ff185828601611dfd565b925050602061200285828601611fba565b9150509250929050565b5f805f6060848603121561202357612022611bcc565b5b5f61203086828701611d50565b935050602061204186828701611d50565b925050604061205286828701611dfd565b9150509250925092565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61209a82611cc9565b810181811067ffffffffffffffff821117156120b9576120b8612064565b5b80604052505050565b5f6120cb611bc3565b90506120d78282612091565b919050565b5f67ffffffffffffffff8211156120f6576120f5612064565b5b6120ff82611cc9565b9050602081019050919050565b828183375f83830152505050565b5f61212c612127846120dc565b6120c2565b90508281526020810184848401111561214857612147612060565b5b61215384828561210c565b509392505050565b5f82601f83011261216f5761216e61205c565b5b813561217f84826020860161211a565b91505092915050565b5f805f80608085870312156121a05761219f611bcc565b5b5f6121ad87828801611dfd565b94505060206121be87828801611dfd565b93505060406121cf87828801611d50565b925050606085013567ffffffffffffffff8111156121f0576121ef611bd0565b5b6121fc8782880161215b565b91505092959194509250565b5f61221282611f2f565b9050919050565b61222281612208565b82525050565b5f60208201905061223b5f830184612219565b92915050565b5f6040820190506122545f830185611e4f565b6122616020830184611dbf565b9392505050565b5f806040838503121561227e5761227d611bcc565b5b5f61228b85828601611dfd565b925050602061229c85828601611dfd565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806122ea57607f821691505b6020821081036122fd576122fc6122a6565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e65785f8201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b5f61235d602c83611c91565b915061236882612303565b604082019050919050565b5f6020820190508181035f83015261238a81612351565b9050919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e655f8201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b5f6123eb602183611c91565b91506123f682612391565b604082019050919050565b5f6020820190508181035f830152612418816123df565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f775f8201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b5f612479603883611c91565b91506124848261241f565b604082019050919050565b5f6020820190508181035f8301526124a68161246d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6124e482611d31565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612516576125156124ad565b5b600182019050919050565b5f61252b82611d31565b915061253683611d31565b925082820390508181111561254e5761254d6124ad565b5b92915050565b7f4e6f7420656e6f75676820766f74657320746f207265766f6b6520415020746f5f8201527f6b656e0000000000000000000000000000000000000000000000000000000000602082015250565b5f6125ae602383611c91565b91506125b982612554565b604082019050919050565b5f6020820190508181035f8301526125db816125a2565b9050919050565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f5f8201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b5f61263c603183611c91565b9150612647826125e2565b604082019050919050565b5f6020820190508181035f83015261266981612630565b9050919050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e65786973745f8201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b5f6126ca602983611c91565b91506126d582612670565b604082019050919050565b5f6020820190508181035f8301526126f7816126be565b9050919050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a655f8201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b5f612758602a83611c91565b9150612763826126fe565b604082019050919050565b5f6020820190508181035f8301526127858161274c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f6127c0602083611c91565b91506127cb8261278c565b602082019050919050565b5f6020820190508181035f8301526127ed816127b4565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c6572000000000000005f82015250565b5f612828601983611c91565b9150612833826127f4565b602082019050919050565b5f6020820190508181035f8301526128558161281c565b9050919050565b7f54696d65204c6f72642063616e6e6f74207265766f6b650000000000000000005f82015250565b5f612890601783611c91565b915061289b8261285c565b602082019050919050565b5f6020820190508181035f8301526128bd81612884565b9050919050565b7f43616e6e6f74207265766f6b65207468652054696d65204c6f726400000000005f82015250565b5f6128f8601b83611c91565b9150612903826128c4565b602082019050919050565b5f6020820190508181035f830152612925816128ec565b9050919050565b7f4e6f7420617574686f72697a656420746f206d616b65207265766f6b652070725f8201527f6f706f73616c0000000000000000000000000000000000000000000000000000602082015250565b5f612986602683611c91565b91506129918261292c565b604082019050919050565b5f6020820190508181035f8301526129b38161297a565b9050919050565b5f67ffffffffffffffff8211156129d4576129d3612064565b5b6129dd82611cc9565b9050602081019050919050565b5f6129fc6129f7846129ba565b6120c2565b905082815260208101848484011115612a1857612a17612060565b5b612a23848285611ca1565b509392505050565b5f82601f830112612a3f57612a3e61205c565b5b8151612a4f8482602086016129ea565b91505092915050565b5f60208284031215612a6d57612a6c611bcc565b5b5f82015167ffffffffffffffff811115612a8a57612a89611bd0565b5b612a9684828501612a2b565b91505092915050565b5f819050919050565b5f612ac2612abd612ab884612a9f565b611f05565b611d31565b9050919050565b612ad281612aa8565b82525050565b5f604082019050612aeb5f830185612ac9565b612af86020830184611e4f565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f612b59602683611c91565b9150612b6482612aff565b604082019050919050565b5f6020820190508181035f830152612b8681612b4d565b9050919050565b7f4552433732313a207472616e73666572206f6620746f6b656e207468617420695f8201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b5f612be7602983611c91565b9150612bf282612b8d565b604082019050919050565b5f6020820190508181035f830152612c1481612bdb565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f612c75602483611c91565b9150612c8082612c1b565b604082019050919050565b5f6020820190508181035f830152612ca281612c69565b9050919050565b5f612cb382611d31565b9150612cbe83611d31565b9250828201905080821115612cd657612cd56124ad565b5b92915050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e65785f8201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b5f612d36602c83611c91565b9150612d4182612cdc565b604082019050919050565b5f6020820190508181035f830152612d6381612d2a565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e2045524337323152655f8201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b5f612dc4603283611c91565b9150612dcf82612d6a565b604082019050919050565b5f6020820190508181035f830152612df181612db8565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f612e1c82612df8565b612e268185612e02565b9350612e36818560208601611ca1565b612e3f81611cc9565b840191505092915050565b5f608082019050612e5d5f830187611dbf565b612e6a6020830186611dbf565b612e776040830185611e4f565b8181036060830152612e898184612e12565b905095945050505050565b5f81519050612ea281611bff565b92915050565b5f60208284031215612ebd57612ebc611bcc565b5b5f612eca84828501612e94565b9150509291505056fea26469706673582212208df6cca196cd7a3a974ad3ba13ee5ad804e548567762976c793e07d4652ee46b64736f6c6343000817003360806040526040518060400160405280601781526020017f68747470733a2f2f6574662e737465766965702e78797a000000000000000000815250600290816200004a919062000367565b5034801562000057575f80fd5b50604051620031a1380380620031a183398181016040528101906200007d9190620004b0565b805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503360015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050620004e0565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200017f57607f821691505b6020821081036200019557620001946200013a565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620001f97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620001bc565b620002058683620001bc565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200024f6200024962000243846200021d565b62000226565b6200021d565b9050919050565b5f819050919050565b6200026a836200022f565b62000282620002798262000256565b848454620001c8565b825550505050565b5f90565b620002986200028a565b620002a58184846200025f565b505050565b5b81811015620002cc57620002c05f826200028e565b600181019050620002ab565b5050565b601f8211156200031b57620002e5816200019b565b620002f084620001ad565b8101602085101562000300578190505b620003186200030f85620001ad565b830182620002aa565b50505b505050565b5f82821c905092915050565b5f6200033d5f198460080262000320565b1980831691505092915050565b5f6200035783836200032c565b9150826002028217905092915050565b620003728262000103565b67ffffffffffffffff8111156200038e576200038d6200010d565b5b6200039a825462000167565b620003a7828285620002d0565b5f60209050601f831160018114620003dd575f8415620003c8578287015190505b620003d485826200034a565b86555062000443565b601f198416620003ed866200019b565b5f5b828110156200041657848901518255600182019150602085019450602081019050620003ef565b8683101562000436578489015162000432601f8916826200032c565b8355505b6001600288020188555050505b505050505050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200047a826200044f565b9050919050565b6200048c816200046e565b811462000497575f80fd5b50565b5f81519050620004aa8162000481565b92915050565b5f60208284031215620004c857620004c76200044b565b5b5f620004d7848285016200049a565b91505092915050565b612cb380620004ee5f395ff3fe608060405234801561000f575f80fd5b5060043610610091575f3560e01c80638fc73484116100645780638fc734841461011d578063bc7ddd951461013b578063c87b56dd14610159578063ca706d5014610189578063d989e308146101b957610091565b80633c4ab134146100955780633c4f743c146100b35780634925ec55146100d15780637734340814610101575b5f80fd5b61009d6101e9565b6040516100aa91906112d5565b60405180910390f35b6100bb610420565b6040516100c8919061136f565b60405180910390f35b6100eb60048036038101906100e691906113cc565b610445565b6040516100f89190611449565b60405180910390f35b61011b60048036038101906101169190611595565b6104b1565b005b6101256105bf565b6040516101329190611449565b60405180910390f35b61014361064b565b60405161015091906115fc565b60405180910390f35b610173600480360381019061016e91906113cc565b61066e565b6040516101809190611449565b60405180910390f35b6101a3600480360381019061019e91906113cc565b610777565b6040516101b09190611449565b60405180910390f35b6101d360048036038101906101ce91906113cc565b610b6a565b6040516101e091906112d5565b60405180910390f35b60605f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b4d0bd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610255573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610279919061164a565b6102b8576040518060400160405280600681526020017f30303738626400000000000000000000000000000000000000000000000000008152506102ef565b6040518060400160405280600681526020017f33383361336300000000000000000000000000000000000000000000000000008152505b90505f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b4d0bd26040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037f919061164a565b6103be576040518060400160405280600681526020017f33383361336300000000000000000000000000000000000000000000000000008152506103f5565b6040518060400160405280600681526020017f30303738626400000000000000000000000000000000000000000000000000008152505b9050818160405160200161040a9291906118bd565b6040516020818303038152906040529250505090565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60605f80831161046d57604051806080016040528060468152602001612c3860469139610487565b6040518060a0016040528060638152602001612bd5606391395b90508060405160200161049a9190611a09565b604051602081830303815290604052915050919050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561051b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061053f9190611a65565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a390611b00565b60405180910390fd5b80600290816105bb9190611d0f565b5050565b600280546105cc90611b4b565b80601f01602080910402602001604051908101604052809291908181526020018280546105f890611b4b565b80156106435780601f1061061a57610100808354040283529160200191610643565b820191905f5260205f20905b81548152906001019060200180831161062657829003601f168201915b505050505081565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60605f6106975f8411610688576106836101e9565b610692565b61069184610b6a565b5b610f62565b6040516020016106a79190611e28565b60405160208183030381529060405290505f6106c284610777565b90505f808511610707576040518060400160405280600981526020017f54696d65204c6f72640000000000000000000000000000000000000000000000815250610730565b610710856110f2565b6040516020016107209190611e6f565b6040516020818303038152906040525b90505f61073c86610445565b90505f828286866002604051602001610759959493929190612232565b60405160208183030381529060405290508095505050505050919050565b60605f821115610916575f670de0b6b3a76400005f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166382cb6b72856040518263ffffffff1660e01b81526004016107e3919061230f565b602060405180830381865afa1580156107fe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610822919061233c565b61082c91906123c1565b90505f670de0b6b3a76400005f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ed0f1c1866040518263ffffffff1660e01b8152600401610890919061230f565b602060405180830381865afa1580156108ab573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108cf919061233c565b6108d991906123c1565b90506108e4826110f2565b6108ed826110f2565b6040516020016108fe929190612569565b60405160208183030381529060405292505050610b65565b610a405f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b603e415f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166385e5a46b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e0919061233c565b6040518263ffffffff1660e01b81526004016109fc919061230f565b602060405180830381865afa158015610a17573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a3b919061233c565b6110f2565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633b4d0bd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aa8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610acc919061164a565b610b0b576040518060400160405280600581526020017f46616c7365000000000000000000000000000000000000000000000000000000815250610b42565b6040518060400160405280600481526020017f54727565000000000000000000000000000000000000000000000000000000008152505b604051602001610b539291906126be565b60405160208183030381529060405290505b919050565b60605f600183610b7a9190612733565b90505f6040518060c0016040528060405180604001604052806040518060400160405280600681526020017f333833613363000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f6666660000000000000000000000000000000000000000000000000000000000815250815250815260200160405180604001604052806040518060400160405280600681526020017f333833613363000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f3030373862640000000000000000000000000000000000000000000000000000815250815250815260200160405180604001604052806040518060400160405280600681526020017f303037386264000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f6666660000000000000000000000000000000000000000000000000000000000815250815250815260200160405180604001604052806040518060400160405280600681526020017f303037386264000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f3338336133630000000000000000000000000000000000000000000000000000815250815250815260200160405180604001604052806040518060400160405280600381526020017f666666000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f3338336133630000000000000000000000000000000000000000000000000000815250815250815260200160405180604001604052806040518060400160405280600381526020017f666666000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f30303738626400000000000000000000000000000000000000000000000000008152508152508152509050808260068110610eb357610eb2612766565b5b60200201515f60028110610eca57610ec9612766565b5b6020020151818360068110610ee257610ee1612766565b5b6020020151600160028110610efa57610ef9612766565b5b6020020151828460068110610f1257610f11612766565b5b60200201515f60028110610f2957610f28612766565b5b6020020151610f37876110f2565b604051602001610f4a9493929190612a35565b60405160208183030381529060405292505050919050565b60605f825190505f8103610f875760405180602001604052805f8152509150506110ed565b5f6003600283610f979190612aa9565b610fa191906123c1565b6004610fad9190612adc565b90505f602082610fbd9190612aa9565b67ffffffffffffffff811115610fd657610fd5611471565b5b6040519080825280601f01601f1916602001820160405280156110085781602001600182028036833780820191505090505b5090505f604051806060016040528060408152602001612b9560409139905060018101602083015f5b868110156110aa5760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050611031565b5060038606600181146110c457600281146110d4576110df565b613d3d60f01b60028303526110df565b603d60f81b60018303525b508484525050819450505050505b919050565b60605f8203611138576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611246565b5f8290505f5b5f821461116757808061115090612b1d565b915050600a8261116091906123c1565b915061113e565b5f8167ffffffffffffffff81111561118257611181611471565b5b6040519080825280601f01601f1916602001820160405280156111b45781602001600182028036833780820191505090505b5090505b5f851461123f576001826111cc9190612733565b9150600a856111db9190612b64565b60306111e79190612aa9565b60f81b8183815181106111fd576111fc612766565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600a8561123891906123c1565b94506111b8565b8093505050505b919050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611282578082015181840152602081019050611267565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6112a78261124b565b6112b18185611255565b93506112c1818560208601611265565b6112ca8161128d565b840191505092915050565b5f6020820190508181035f8301526112ed818461129d565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f819050919050565b5f61133761133261132d846112f5565b611314565b6112f5565b9050919050565b5f6113488261131d565b9050919050565b5f6113598261133e565b9050919050565b6113698161134f565b82525050565b5f6020820190506113825f830184611360565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f819050919050565b6113ab81611399565b81146113b5575f80fd5b50565b5f813590506113c6816113a2565b92915050565b5f602082840312156113e1576113e0611391565b5b5f6113ee848285016113b8565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f61141b826113f7565b6114258185611401565b9350611435818560208601611265565b61143e8161128d565b840191505092915050565b5f6020820190508181035f8301526114618184611411565b905092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6114a78261128d565b810181811067ffffffffffffffff821117156114c6576114c5611471565b5b80604052505050565b5f6114d8611388565b90506114e4828261149e565b919050565b5f67ffffffffffffffff82111561150357611502611471565b5b61150c8261128d565b9050602081019050919050565b828183375f83830152505050565b5f611539611534846114e9565b6114cf565b9050828152602081018484840111156115555761155461146d565b5b611560848285611519565b509392505050565b5f82601f83011261157c5761157b611469565b5b813561158c848260208601611527565b91505092915050565b5f602082840312156115aa576115a9611391565b5b5f82013567ffffffffffffffff8111156115c7576115c6611395565b5b6115d384828501611568565b91505092915050565b5f6115e68261133e565b9050919050565b6115f6816115dc565b82525050565b5f60208201905061160f5f8301846115ed565b92915050565b5f8115159050919050565b61162981611615565b8114611633575f80fd5b50565b5f8151905061164481611620565b92915050565b5f6020828403121561165f5761165e611391565b5b5f61166c84828501611636565b91505092915050565b5f81905092915050565b7f3c7376672076696577426f783d2230203020353030203530302220786d6c6e735f8201527f3d22687474703a2f2f7777772e77332e6f72672f323030302f737667223e3c6360208201527f6972636c652063783d22323530222063793d223235302220723d22323530222060408201527f66696c6c3d222300000000000000000000000000000000000000000000000000606082015250565b5f611725606783611675565b91506117308261167f565b606782019050919050565b5f611745826113f7565b61174f8185611675565b935061175f818560208601611265565b80840191505092915050565b7f223e3c2f636972636c653e3c636972636c652063783d22323530222063793d225f8201527f3235302220723d22323330222066696c6c3d2223000000000000000000000000602082015250565b5f6117c5603483611675565b91506117d08261176b565b603482019050919050565b7f223e3c2f636972636c653e3c7465787420783d223235302220793d22323730225f8201527f20646f6d696e616e742d626173656c696e653d226d6964646c6522207465787460208201527f2d616e63686f723d226d6964646c65222066696c6c3d22236666662220666f6e60408201527f742d73697a653d223235302220666f6e742d66616d696c793d2273616e732d7360608201527f65726966223e544c3c2f746578743e3c2f7376673e0000000000000000000000608082015250565b5f6118a7609583611675565b91506118b2826117db565b609582019050919050565b5f6118c782611719565b91506118d3828561173b565b91506118de826117b9565b91506118ea828461173b565b91506118f58261189b565b91508190509392505050565b7f455446207365656b7320746f2073696d756c61746520746865206578706572695f8201527f656e6365206f66206f776e696e6720736861726573206f6620616e206578636860208201527f616e67652d7472616465642066756e642074686174207365656b7320746f207260408201527f65666c6563742c206265666f7265206665657320616e6420657870656e73657360608201527f2c2074686520706572666f726d616e6365206f6620746865207072696365206f60808201527f6620457468657265756d2e20000000000000000000000000000000000000000060a082015250565b5f6119f360ac83611675565b91506119fe82611901565b60ac82019050919050565b5f611a13826119e7565b9150611a1f828461173b565b915081905092915050565b5f611a34826112f5565b9050919050565b611a4481611a2a565b8114611a4e575f80fd5b50565b5f81519050611a5f81611a3b565b92915050565b5f60208284031215611a7a57611a79611391565b5b5f611a8784828501611a51565b91505092915050565b7f4f6e6c7920415020636f6e7472616374206f776e65722063616e2073657420755f8201527f726c000000000000000000000000000000000000000000000000000000000000602082015250565b5f611aea602283611401565b9150611af582611a90565b604082019050919050565b5f6020820190508181035f830152611b1781611ade565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611b6257607f821691505b602082108103611b7557611b74611b1e565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302611bd77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611b9c565b611be18683611b9c565b95508019841693508086168417925050509392505050565b5f611c13611c0e611c0984611399565b611314565b611399565b9050919050565b5f819050919050565b611c2c83611bf9565b611c40611c3882611c1a565b848454611ba8565b825550505050565b5f90565b611c54611c48565b611c5f818484611c23565b505050565b5b81811015611c8257611c775f82611c4c565b600181019050611c65565b5050565b601f821115611cc757611c9881611b7b565b611ca184611b8d565b81016020851015611cb0578190505b611cc4611cbc85611b8d565b830182611c64565b50505b505050565b5f82821c905092915050565b5f611ce75f1984600802611ccc565b1980831691505092915050565b5f611cff8383611cd8565b9150826002028217905092915050565b611d18826113f7565b67ffffffffffffffff811115611d3157611d30611471565b5b611d3b8254611b4b565b611d46828285611c86565b5f60209050601f831160018114611d77575f8415611d65578287015190505b611d6f8582611cf4565b865550611dd6565b601f198416611d8586611b7b565b5f5b82811015611dac57848901518255600182019150602085019450602081019050611d87565b86831015611dc95784890151611dc5601f891682611cd8565b8355505b6001600288020188555050505b505050505050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000005f82015250565b5f611e12601a83611675565b9150611e1d82611dde565b601a82019050919050565b5f611e3282611e06565b9150611e3e828461173b565b915081905092915050565b7f417574686f72697a6564205061727469636970616e7420000000000000000000815250565b5f611e7982611e49565b601782019150611e89828461173b565b915081905092915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c00000000005f82015250565b5f611ec8601b83611675565b9150611ed382611e94565b601b82019050919050565b7f7b226e616d65223a2022000000000000000000000000000000000000000000005f82015250565b5f611f12600a83611675565b9150611f1d82611ede565b600a82019050919050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f611f5c600283611675565b9150611f6782611f28565b600282019050919050565b7f226465736372697074696f6e223a2022000000000000000000000000000000005f82015250565b5f611fa6601083611675565b9150611fb182611f72565b601082019050919050565b7f22696d616765223a2022000000000000000000000000000000000000000000005f82015250565b5f611ff0600a83611675565b9150611ffb82611fbc565b600a82019050919050565b5f81905092915050565b5f61201a8261124b565b6120248185612006565b9350612034818560208601611265565b80840191505092915050565b7f2261747472696275746573223a200000000000000000000000000000000000005f82015250565b5f612074600e83611675565b915061207f82612040565b600e82019050919050565b7f2c000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6120be600183611675565b91506120c98261208a565b600182019050919050565b7f2265787465726e616c5f75726c223a20220000000000000000000000000000005f82015250565b5f612108601183611675565b9150612113826120d4565b601182019050919050565b5f815461212a81611b4b565b6121348186611675565b9450600182165f811461214e576001811461216357612195565b60ff1983168652811515820286019350612195565b61216c85611b7b565b5f5b8381101561218d5781548189015260018201915060208101905061216e565b838801955050505b50505092915050565b7f22000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6121d2600183611675565b91506121dd8261219e565b600182019050919050565b7f7d000000000000000000000000000000000000000000000000000000000000005f82015250565b5f61221c600183611675565b9150612227826121e8565b600182019050919050565b5f61223c82611ebc565b915061224782611f06565b9150612253828861173b565b915061225e82611f50565b915061226982611f9a565b9150612275828761173b565b915061228082611f50565b915061228b82611fe4565b91506122978286612010565b91506122a282611f50565b91506122ad82612068565b91506122b9828561173b565b91506122c4826120b2565b91506122cf826120fc565b91506122db828461211e565b91506122e6826121c6565b91506122f182612210565b91508190509695505050505050565b61230981611399565b82525050565b5f6020820190506123225f830184612300565b92915050565b5f81519050612336816113a2565b92915050565b5f6020828403121561235157612350611391565b5b5f61235e84828501612328565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6123cb82611399565b91506123d683611399565b9250826123e6576123e5612367565b5b828204905092915050565b7f5b00000000000000000000000000000000000000000000000000000000000000815250565b7f7b2274726169745f74797065223a20225368617265732043726561746564222c5f8201527f202276616c7565223a2022000000000000000000000000000000000000000000602082015250565b5f612471602b83611675565b915061247c82612417565b602b82019050919050565b7f227d2c0000000000000000000000000000000000000000000000000000000000815250565b7f7b2274726169745f74797065223a20225368617265732052656465656d6564225f8201527f2c202276616c7565223a20220000000000000000000000000000000000000000602082015250565b5f612507602c83611675565b9150612512826124ad565b602c82019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000815250565b7f5d00000000000000000000000000000000000000000000000000000000000000815250565b5f612573826123f1565b60018201915061258282612465565b915061258e828561173b565b915061259982612487565b6003820191506125a8826124fb565b91506125b4828461173b565b91506125bf8261251d565b6002820191506125ce82612543565b6001820191508190509392505050565b7f7b2274726169745f74797065223a20224d61726b657420486f6c6964617973205f8201527f53657420466f722059656172222c202276616c7565223a202200000000000000602082015250565b5f612638603983611675565b9150612643826125de565b603982019050919050565b7f7b2274726169745f74797065223a2022497320445354222c202276616c7565225f8201527f3a20220000000000000000000000000000000000000000000000000000000000602082015250565b5f6126a8602383611675565b91506126b38261264e565b602382019050919050565b5f6126c8826123f1565b6001820191506126d78261262c565b91506126e3828561173b565b91506126ee82612487565b6003820191506126fd8261269c565b9150612709828461173b565b91506127148261251d565b60028201915061272382612543565b6001820191508190509392505050565b5f61273d82611399565b915061274883611399565b92508282039050818111156127605761275f612394565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f3c7376672076696577426f783d2230203020353030203530302220786d6c6e735f8201527f3d22687474703a2f2f7777772e77332e6f72672f323030302f737667223e3c7360208201527f74796c653e746578747b666f6e742d66616d696c793a6d6f6e6f73706163653b60408201527f66696c6c3a230000000000000000000000000000000000000000000000000000606082015250565b5f612839606683611675565b915061284482612793565b606682019050919050565b7f3b666f6e742d73697a653a31383070787d726563747b66696c6c3a23000000005f82015250565b5f612883601c83611675565b915061288e8261284f565b601c82019050919050565b7f3b7374726f6b653a2300000000000000000000000000000000000000000000005f82015250565b5f6128cd600983611675565b91506128d882612899565b600982019050919050565b7f3b7374726f6b652d77696474683a333570787d3c2f7374796c653e3c726563745f8201527f20783d22302220793d2230222077696474683d2235303022206865696768743d60208201527f22353030223e3c2f726563743e3c7465787420636c6173733d2266696c6c4c6960408201527f6768742220783d223530252220793d223530252220646f6d696e616e742d626160608201527f73656c696e653d226d6964646c652220746578742d616e63686f723d226d696460808201527f646c65223e41500000000000000000000000000000000000000000000000000060a082015250565b5f6129d560a783611675565b91506129e0826128e3565b60a782019050919050565b7f3c2f746578743e3c2f7376673e000000000000000000000000000000000000005f82015250565b5f612a1f600d83611675565b9150612a2a826129eb565b600d82019050919050565b5f612a3f8261282d565b9150612a4b828761173b565b9150612a5682612877565b9150612a62828661173b565b9150612a6d826128c1565b9150612a79828561173b565b9150612a84826129c9565b9150612a90828461173b565b9150612a9b82612a13565b915081905095945050505050565b5f612ab382611399565b9150612abe83611399565b9250828201905080821115612ad657612ad5612394565b5b92915050565b5f612ae682611399565b9150612af183611399565b9250828202612aff81611399565b91508282048414831517612b1657612b15612394565b5b5092915050565b5f612b2782611399565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b5957612b58612394565b5b600182019050919050565b5f612b6e82611399565b9150612b7983611399565b925082612b8957612b88612367565b5b82820690509291505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f417574686f72697a6564205061727469636970616e74732068617665207468652072696768742028627574206e6f7420746865206f626c69676174696f6e2920746f2063726561746520616e642072656465656d20736861726573206f66204554462e5468652054696d65204c6f7264206861732074686520736f6c65206162696c69747920746f206465636c617265204d61726b657420486f6c696461797320616e64204453542ea2646970667358221220cc1f1ca317829c4312ec8fe7f8f1184c973b5ffc68db0b9ed6eff72b6935856164736f6c63430008170033
Deployed Bytecode
0x6080604052600436106101b6575f3560e01c806382cb6b72116100eb578063bc6e660411610089578063d4ce85f311610063578063d4ce85f31461065a578063d878016114610684578063dd62ed3e146106ac578063f01fe692146106e8576101b6565b8063bc6e6604146105dc578063c1590cd714610606578063c1c407ac14610630576101b6565b80639c2f5661116100c55780639c2f5661146105125780639d55cb581461053a578063a457c2d714610564578063a9059cbb146105a0576101b6565b806382cb6b721461048257806385e5a46b146104be57806395d89b41146104e8576101b6565b8063395093511161015857806361873b441161013257806361873b44146103a457806370a08231146103e05780637ed0f1c11461041c57806380477a4c14610458576101b6565b806339509351146103025780633b4d0bd21461033e5780635b603e4114610368576101b6565b806323b872dd1161019457806323b872dd1461024a57806324f5ffdd14610286578063313ce567146102ae5780633508e27a146102d8576101b6565b806306fdde03146101ba578063095ea7b3146101e457806318160ddd14610220575b5f80fd5b3480156101c5575f80fd5b506101ce610704565b6040516101db9190611ea4565b60405180910390f35b3480156101ef575f80fd5b5061020a60048036038101906102059190611f55565b610794565b6040516102179190611fad565b60405180910390f35b34801561022b575f80fd5b506102346107b6565b6040516102419190611fd5565b60405180910390f35b348015610255575f80fd5b50610270600480360381019061026b9190611fee565b6107bf565b60405161027d9190611fad565b60405180910390f35b348015610291575f80fd5b506102ac60048036038101906102a7919061203e565b6107ed565b005b3480156102b9575f80fd5b506102c2610afc565b6040516102cf9190612084565b60405180910390f35b3480156102e3575f80fd5b506102ec610b04565b6040516102f99190611fd5565b60405180910390f35b34801561030d575f80fd5b5061032860048036038101906103239190611f55565b610b0a565b6040516103359190611fad565b60405180910390f35b348015610349575f80fd5b50610352610b40565b60405161035f9190611fad565b60405180910390f35b348015610373575f80fd5b5061038e6004803603810190610389919061203e565b610b52565b60405161039b9190611fd5565b60405180910390f35b3480156103af575f80fd5b506103ca60048036038101906103c5919061203e565b610b67565b6040516103d79190611fad565b60405180910390f35b3480156103eb575f80fd5b506104066004803603810190610401919061209d565b610b84565b6040516104139190611fd5565b60405180910390f35b348015610427575f80fd5b50610442600480360381019061043d919061203e565b610bc9565b60405161044f9190611fd5565b60405180910390f35b348015610463575f80fd5b5061046c610bde565b6040516104799190611fd5565b60405180910390f35b34801561048d575f80fd5b506104a860048036038101906104a3919061203e565b610c37565b6040516104b59190611fd5565b60405180910390f35b3480156104c9575f80fd5b506104d2610c4c565b6040516104df9190611fd5565b60405180910390f35b3480156104f3575f80fd5b506104fc610c71565b6040516105099190611ea4565b60405180910390f35b34801561051d575f80fd5b50610538600480360381019061053391906120f2565b610d01565b005b348015610545575f80fd5b5061054e610ee3565b60405161055b9190612178565b60405180910390f35b34801561056f575f80fd5b5061058a60048036038101906105859190611f55565b610f09565b6040516105979190611fad565b60405180910390f35b3480156105ab575f80fd5b506105c660048036038101906105c19190611f55565b610f7e565b6040516105d39190611fad565b60405180910390f35b3480156105e7575f80fd5b506105f0610fa0565b6040516105fd9190611fd5565b60405180910390f35b348015610611575f80fd5b5061061a610fa6565b6040516106279190611fd5565b60405180910390f35b34801561063b575f80fd5b50610644610fd2565b6040516106519190611fd5565b60405180910390f35b348015610665575f80fd5b5061066e610fda565b60405161067b9190611fad565b60405180910390f35b34801561068f575f80fd5b506106aa60048036038101906106a59190612191565b611096565b005b3480156106b7575f80fd5b506106d260048036038101906106cd91906121e1565b611324565b6040516106df9190611fd5565b60405180910390f35b61070260048036038101906106fd919061221f565b6113a6565b005b6060600380546107139061228a565b80601f016020809104026020016040519081016040528092919081815260200182805461073f9061228a565b801561078a5780601f106107615761010080835404028352916020019161078a565b820191905f5260205f20905b81548152906001019060200180831161076d57829003601f168201915b5050505050905090565b5f8061079e6115f7565b90506107ab8185856115fe565b600191505092915050565b5f600254905090565b5f806107c96115f7565b90506107d68582856117c1565b6107e185858561184c565b60019150509392505050565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e5f6040518263ffffffff1660e01b815260040161084891906122f3565b602060405180830381865afa158015610863573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108879190612320565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108eb906123bb565b60405180910390fd5b600a60095f610901610c4c565b81526020019081526020015f20541061094f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109469061246f565b60405180910390fd5b610957610bde565b811015801561097a575061016e61096c610bde565b61097691906124ba565b8111155b6109b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109b090612583565b60405180910390fd5b60085f8281526020019081526020015f205f9054906101000a900460ff16610af957600160085f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555060095f610a0f610c4c565b81526020019081526020015f205f815480929190610a2c906125a1565b9190505550600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a1c34fb5f6040518263ffffffff1660e01b8152600401610a8c91906122f3565b5f604051808303815f87803b158015610aa3575f80fd5b505af1158015610ab5573d5f803e3d5ffd5b50505050610ac1610c4c565b7f59ad40d521feb27052c7e7e3741f839354d35da2bd0fc555bd87d097635b906582604051610af09190611fd5565b60405180910390a25b50565b5f6012905090565b615b6881565b5f80610b146115f7565b9050610b35818585610b268589611324565b610b3091906124ba565b6115fe565b600191505092915050565b60055f9054906101000a900460ff1681565b6009602052805f5260405f205f915090505481565b6008602052805f5260405f205f915054906101000a900460ff1681565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6007602052805f5260405f205f915090505481565b5f8060055f9054906101000a900460ff16610bf9575f610bfd565b610e105b61ffff1690505f81636613ff6842610c1591906125e8565b610c1f91906124ba565b90506201518081610c309190612648565b9250505090565b6006602052805f5260405f205f915090505481565b5f6301e13380636613ff6842610c6291906125e8565b610c6c9190612648565b905090565b606060048054610c809061228a565b80601f0160208091040260200160405190810160405280929190818152602001828054610cac9061228a565b8015610cf75780601f10610cce57610100808354040283529160200191610cf7565b820191905f5260205f20905b815481529060010190602001808311610cda57829003601f168201915b5050505050905090565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e5f6040518263ffffffff1660e01b8152600401610d5c91906122f3565b602060405180830381865afa158015610d77573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d9b9190612320565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dff906126e8565b60405180910390fd5b8060055f6101000a81548160ff021916908315150217905550600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a1c34fb5f6040518263ffffffff1660e01b8152600401610e7c91906122f3565b5f604051808303815f87803b158015610e93575f80fd5b505af1158015610ea5573d5f803e3d5ffd5b505050507fc73ba96388f9e70004b21ddf94e0198df57b66950d133faaa024224e87a9191c81604051610ed89190611fad565b60405180910390a150565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f80610f136115f7565b90505f610f208286611324565b905083811015610f65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5c90612776565b60405180910390fd5b610f7282868684036115fe565b60019250505092915050565b5f80610f886115f7565b9050610f9581858561184c565b600191505092915050565b61271081565b5f670de0b6b3a7640000610fb86107b6565b610fc29190612648565b47610fcd9190612648565b905090565b636613ff6881565b5f8060055f9054906101000a900460ff16610ff5575f610ff9565b610e105b61ffff1690505f81636613ff684261101191906125e8565b61101b91906124ba565b90505f620151808261102d9190612794565b90505f620151808361103f9190612648565b90505f60078261104f9190612794565b905060058160ff1610801561107f575060085f8381526020019081526020015f205f9054906101000a900460ff16155b801561108c5750615b6883105b9550505050505090565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016110f19190611fd5565b602060405180830381865afa15801561110c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111309190612320565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461119d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119490612834565b60405180910390fd5b5f83116111df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d69061289c565b60405180910390fd5b6111e93382611ab8565b5f8273ffffffffffffffffffffffffffffffffffffffff166108fc612710846112129190612648565b90811502906040515f60405180830381858888f19350505050905080611236575f80fd5b8160075f8681526020019081526020015f205f82825461125691906124ba565b92505081905550600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a1c34fb856040518263ffffffff1660e01b81526004016112b89190611fd5565b5f604051808303815f87803b1580156112cf575f80fd5b505af11580156112e1573d5f803e3d5ffd5b505050507fba7975764e321f07896c9c9852213d675ea0ab36b67e22a7e6d762b0fddd30d984836040516113169291906128ba565b60405180910390a150505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004016114019190611fd5565b602060405180830381865afa15801561141c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114409190612320565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a490612951565b60405180910390fd5b5f82116114ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e6906129b9565b60405180910390fd5b5f612710346114fe91906129d7565b905061150a8282611c7b565b8060065f8581526020019081526020015f205f82825461152a91906124ba565b92505081905550600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a1c34fb846040518263ffffffff1660e01b815260040161158c9190611fd5565b5f604051808303815f87803b1580156115a3575f80fd5b505af11580156115b5573d5f803e3d5ffd5b505050507f7e9a979db69ea4a9dfb969aa39223836ca1b379955de49444c5a4cd2f9e7dbfe83826040516115ea9291906128ba565b60405180910390a1505050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361166c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166390612a88565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d190612b16565b60405180910390fd5b8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516117b49190611fd5565b60405180910390a3505050565b5f6117cc8484611324565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146118465781811015611838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182f90612b7e565b60405180910390fd5b61184584848484036115fe565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036118ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b190612c0c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611928576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191f90612c9a565b60405180910390fd5b611933838383611dc9565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156119b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ad90612d28565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550815f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611a9f9190611fd5565b60405180910390a3611ab2848484611e15565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1d90612db6565b60405180910390fd5b611b31825f83611dc9565b5f805f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bab90612e44565b60405180910390fd5b8181035f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508160025f82825403925050819055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c639190611fd5565b60405180910390a3611c76835f84611e15565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce090612eac565b60405180910390fd5b611cf45f8383611dc9565b8060025f828254611d0591906124ba565b92505081905550805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508173ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611db29190611fd5565b60405180910390a3611dc55f8383611e15565b5050565b611dd1610fda565b611e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0790612f3a565b60405180910390fd5b505050565b505050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611e51578082015181840152602081019050611e36565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611e7682611e1a565b611e808185611e24565b9350611e90818560208601611e34565b611e9981611e5c565b840191505092915050565b5f6020820190508181035f830152611ebc8184611e6c565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611ef182611ec8565b9050919050565b611f0181611ee7565b8114611f0b575f80fd5b50565b5f81359050611f1c81611ef8565b92915050565b5f819050919050565b611f3481611f22565b8114611f3e575f80fd5b50565b5f81359050611f4f81611f2b565b92915050565b5f8060408385031215611f6b57611f6a611ec4565b5b5f611f7885828601611f0e565b9250506020611f8985828601611f41565b9150509250929050565b5f8115159050919050565b611fa781611f93565b82525050565b5f602082019050611fc05f830184611f9e565b92915050565b611fcf81611f22565b82525050565b5f602082019050611fe85f830184611fc6565b92915050565b5f805f6060848603121561200557612004611ec4565b5b5f61201286828701611f0e565b935050602061202386828701611f0e565b925050604061203486828701611f41565b9150509250925092565b5f6020828403121561205357612052611ec4565b5b5f61206084828501611f41565b91505092915050565b5f60ff82169050919050565b61207e81612069565b82525050565b5f6020820190506120975f830184612075565b92915050565b5f602082840312156120b2576120b1611ec4565b5b5f6120bf84828501611f0e565b91505092915050565b6120d181611f93565b81146120db575f80fd5b50565b5f813590506120ec816120c8565b92915050565b5f6020828403121561210757612106611ec4565b5b5f612114848285016120de565b91505092915050565b5f819050919050565b5f61214061213b61213684611ec8565b61211d565b611ec8565b9050919050565b5f61215182612126565b9050919050565b5f61216282612147565b9050919050565b61217281612158565b82525050565b5f60208201905061218b5f830184612169565b92915050565b5f805f606084860312156121a8576121a7611ec4565b5b5f6121b586828701611f41565b93505060206121c686828701611f0e565b92505060406121d786828701611f41565b9150509250925092565b5f80604083850312156121f7576121f6611ec4565b5b5f61220485828601611f0e565b925050602061221585828601611f0e565b9150509250929050565b5f806040838503121561223557612234611ec4565b5b5f61224285828601611f41565b925050602061225385828601611f0e565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806122a157607f821691505b6020821081036122b4576122b361225d565b5b50919050565b5f819050919050565b5f6122dd6122d86122d3846122ba565b61211d565b611f22565b9050919050565b6122ed816122c3565b82525050565b5f6020820190506123065f8301846122e4565b92915050565b5f8151905061231a81611ef8565b92915050565b5f6020828403121561233557612334611ec4565b5b5f6123428482850161230c565b91505092915050565b7f4f6e6c79207468652054696d65204c6f72642063616e206465636c617265204d5f8201527f61726b657420486f6c6964617973000000000000000000000000000000000000602082015250565b5f6123a5602e83611e24565b91506123b08261234b565b604082019050919050565b5f6020820190508181035f8301526123d281612399565b9050919050565b7f5468652054696d65204c6f72642063616e206f6e6c79206465636c61726520315f8201527f30204d61726b657420486f6c6964617973207065722066697363616c2079656160208201527f7200000000000000000000000000000000000000000000000000000000000000604082015250565b5f612459604183611e24565b9150612464826123d9565b606082019050919050565b5f6020820190508181035f8301526124868161244d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6124c482611f22565b91506124cf83611f22565b92508282019050808211156124e7576124e661248d565b5b92915050565b7f5468652054696d65204c6f72642063616e206f6e6c79206465636c617265204d5f8201527f61726b657420486f6c69646179732077697468696e207468652066697363616c60208201527f2079656172000000000000000000000000000000000000000000000000000000604082015250565b5f61256d604583611e24565b9150612578826124ed565b606082019050919050565b5f6020820190508181035f83015261259a81612561565b9050919050565b5f6125ab82611f22565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036125dd576125dc61248d565b5b600182019050919050565b5f6125f282611f22565b91506125fd83611f22565b92508282039050818111156126155761261461248d565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61265282611f22565b915061265d83611f22565b92508261266d5761266c61261b565b5b828204905092915050565b7f4f6e6c79207468652054696d65204c6f72642063616e206465636c61726520445f8201527f5354000000000000000000000000000000000000000000000000000000000000602082015250565b5f6126d2602283611e24565b91506126dd82612678565b604082019050919050565b5f6020820190508181035f8301526126ff816126c6565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f775f8201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b5f612760602583611e24565b915061276b82612706565b604082019050919050565b5f6020820190508181035f83015261278d81612754565b9050919050565b5f61279e82611f22565b91506127a983611f22565b9250826127b9576127b861261b565b5b828206905092915050565b7f4f6e6c7920417574686f72697a6564205061727469636970616e74732063616e5f8201527f2072656465656d20746f6b656e73000000000000000000000000000000000000602082015250565b5f61281e602e83611e24565b9150612829826127c4565b604082019050919050565b5f6020820190508181035f83015261284b81612812565b9050919050565b7f54696d65204c6f72642063616e6e6f742072656465656d20746f6b656e7300005f82015250565b5f612886601e83611e24565b915061289182612852565b602082019050919050565b5f6020820190508181035f8301526128b38161287a565b9050919050565b5f6040820190506128cd5f830185611fc6565b6128da6020830184611fc6565b9392505050565b7f4f6e6c7920417574686f72697a6564205061727469636970616e74732063616e5f8201527f2063726561746520746f6b656e73000000000000000000000000000000000000602082015250565b5f61293b602e83611e24565b9150612946826128e1565b604082019050919050565b5f6020820190508181035f8301526129688161292f565b9050919050565b7f54696d65204c6f72642063616e6e6f742063726561746520746f6b656e7300005f82015250565b5f6129a3601e83611e24565b91506129ae8261296f565b602082019050919050565b5f6020820190508181035f8301526129d081612997565b9050919050565b5f6129e182611f22565b91506129ec83611f22565b92508282026129fa81611f22565b91508282048414831517612a1157612a1061248d565b5b5092915050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f612a72602483611e24565b9150612a7d82612a18565b604082019050919050565b5f6020820190508181035f830152612a9f81612a66565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f2061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f612b00602283611e24565b9150612b0b82612aa6565b604082019050919050565b5f6020820190508181035f830152612b2d81612af4565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000005f82015250565b5f612b68601d83611e24565b9150612b7382612b34565b602082019050919050565b5f6020820190508181035f830152612b9581612b5c565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f2061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f612bf6602583611e24565b9150612c0182612b9c565b604082019050919050565b5f6020820190508181035f830152612c2381612bea565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f612c84602383611e24565b9150612c8f82612c2a565b604082019050919050565b5f6020820190508181035f830152612cb181612c78565b9050919050565b7f45524332303a207472616e7366657220616d6f756e74206578636565647320625f8201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b5f612d12602683611e24565b9150612d1d82612cb8565b604082019050919050565b5f6020820190508181035f830152612d3f81612d06565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f612da0602183611e24565b9150612dab82612d46565b604082019050919050565b5f6020820190508181035f830152612dcd81612d94565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e5f8201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b5f612e2e602283611e24565b9150612e3982612dd4565b604082019050919050565b5f6020820190508181035f830152612e5b81612e22565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f2061646472657373005f82015250565b5f612e96601f83611e24565b9150612ea182612e62565b602082019050919050565b5f6020820190508181035f830152612ec381612e8a565b9050919050565b7f43616e206f6e6c79207472616e7366657220647572696e67206d61726b6574205f8201527f74726164696e6720686f75727300000000000000000000000000000000000000602082015250565b5f612f24602d83611e24565b9150612f2f82612eca565b604082019050919050565b5f6020820190508181035f830152612f5181612f18565b905091905056fea2646970667358221220589505703d45bf636cd888910ca759e61683f1bf8890829c3998bcf44b9193ce64736f6c63430008170033
Deployed Bytecode Sourcemap
129:4032:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41117:98:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43403:197;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42214:106;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44162:256;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3248:673:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42063:91:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;300:67:2;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44813:234:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;372:17:2;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;595:63;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;544:47;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42378:125:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;497:43:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1237:213;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;451:42;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1121:112;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41328:102:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3925:234:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;394:52;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45534:427:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42699:189;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;155:46:2;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;981:114;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;205:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1454:531;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2687:530;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42946:149:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2199:484:2;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;41117:98:1;41171:13;41203:5;41196:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41117:98;:::o;43403:197::-;43486:4;43502:13;43518:12;:10;:12::i;:::-;43502:28;;43540:32;43549:5;43556:7;43565:6;43540:8;:32::i;:::-;43589:4;43582:11;;;43403:197;;;;:::o;42214:106::-;42275:7;42301:12;;42294:19;;42214:106;:::o;44162:256::-;44259:4;44275:15;44293:12;:10;:12::i;:::-;44275:30;;44315:38;44331:4;44337:7;44346:6;44315:15;:38::i;:::-;44363:27;44373:4;44379:2;44383:6;44363:9;:27::i;:::-;44407:4;44400:11;;;44162:256;;;;;:::o;3248:673:2:-;3328:22;;;;;;;;;;;:30;;;3359:1;3328:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3314:47;;:10;:47;;;3306:106;;;;;;;;;;;;:::i;:::-;;;;;;;;;3473:2;3426:28;:44;3455:14;:12;:14::i;:::-;3426:44;;;;;;;;;;;;:49;3418:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;3566:13;:11;:13::i;:::-;3559:3;:20;;:52;;;;;3607:3;3591:13;:11;:13::i;:::-;:19;;;;:::i;:::-;3583:3;:28;;3559:52;3551:134;;;;;;;;;;;;:::i;:::-;;;;;;;;;3697:15;:20;3713:3;3697:20;;;;;;;;;;;;;;;;;;;;;3692:225;;3750:4;3727:15;:20;3743:3;3727:20;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;3762:28;:44;3791:14;:12;:14::i;:::-;3762:44;;;;;;;;;;;;:46;;;;;;;;;:::i;:::-;;;;;;3816:22;;;;;;;;;;;:37;;;3854:1;3816:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3890:14;:12;:14::i;:::-;3869:41;3906:3;3869:41;;;;;;:::i;:::-;;;;;;;;3692:225;3248:673;:::o;42063:91:1:-;42121:5;42145:2;42138:9;;42063:91;:::o;300:67:2:-;347:20;300:67;:::o;44813:234:1:-;44901:4;44917:13;44933:12;:10;:12::i;:::-;44917:28;;44955:64;44964:5;44971:7;45008:10;44980:25;44990:5;44997:7;44980:9;:25::i;:::-;:38;;;;:::i;:::-;44955:8;:64::i;:::-;45036:4;45029:11;;;44813:234;;;;:::o;372:17:2:-;;;;;;;;;;;;;:::o;595:63::-;;;;;;;;;;;;;;;;;:::o;544:47::-;;;;;;;;;;;;;;;;;;;;;;:::o;42378:125:1:-;42452:7;42478:9;:18;42488:7;42478:18;;;;;;;;;;;;;;;;42471:25;;42378:125;;;:::o;497:43:2:-;;;;;;;;;;;;;;;;;:::o;1237:213::-;1281:7;1296:21;1320:5;;;;;;;;;;;:19;;1338:1;1320:19;;;1328:7;1320:19;1296:43;;;;1345:19;1399:13;241:10;1368:15;:27;;;;:::i;:::-;1367:45;;;;:::i;:::-;1345:67;;1439:6;1425:11;:20;;;;:::i;:::-;1418:27;;;;1237:213;:::o;451:42::-;;;;;;;;;;;;;;;;;:::o;1121:112::-;1166:7;1220:8;241:10;1189:15;:27;;;;:::i;:::-;1188:40;;;;:::i;:::-;1181:47;;1121:112;:::o;41328:102:1:-;41384:13;41416:7;41409:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41328:102;:::o;3925:234:2:-;3992:22;;;;;;;;;;;:30;;;4023:1;3992:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3978:47;;:10;:47;;;3970:94;;;;;;;;;;;;:::i;:::-;;;;;;;;;4078:3;4070:5;;:11;;;;;;;;;;;;;;;;;;4087:22;;;;;;;;;;;:37;;;4125:1;4087:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4139:15;4150:3;4139:15;;;;;;:::i;:::-;;;;;;;;3925:234;:::o;394:52::-;;;;;;;;;;;;;:::o;45534:427:1:-;45627:4;45643:13;45659:12;:10;:12::i;:::-;45643:28;;45681:24;45708:25;45718:5;45725:7;45708:9;:25::i;:::-;45681:52;;45771:15;45751:16;:35;;45743:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;45862:60;45871:5;45878:7;45906:15;45887:16;:34;45862:8;:60::i;:::-;45950:4;45943:11;;;;45534:427;;;;:::o;42699:189::-;42778:4;42794:13;42810:12;:10;:12::i;:::-;42794:28;;42832;42842:5;42849:2;42853:6;42832:9;:28::i;:::-;42877:4;42870:11;;;42699:189;;;;:::o;155:46:2:-;196:5;155:46;:::o;981:114::-;1017:7;1082;1066:13;:11;:13::i;:::-;:23;;;;:::i;:::-;1040:21;1039:51;;;;:::i;:::-;1032:58;;981:114;:::o;205:46::-;241:10;205:46;:::o;1454:531::-;1499:4;1511:21;1535:5;;;;;;;;;;;:19;;1553:1;1535:19;;;1543:7;1535:19;1511:43;;;;1560:19;1614:13;241:10;1583:15;:27;;;;:::i;:::-;1582:45;;;;:::i;:::-;1560:67;;1633:18;1668:6;1654:11;:20;;;;:::i;:::-;1633:41;;1680:20;1717:6;1703:11;:20;;;;:::i;:::-;1680:43;;1729:15;1768:1;1753:12;:16;;;;:::i;:::-;1729:41;;1804:1;1792:9;:13;;;:47;;;;;1810:15;:29;1826:12;1810:29;;;;;;;;;;;;;;;;;;;;;1809:30;1792:47;:132;;;;;347:20;1891:10;:33;1792:132;1777:203;;;;;;;1454:531;:::o;2687:530::-;2798:22;;;;;;;;;;;:30;;;2829:7;2798:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2784:53;;:10;:53;;;2776:112;;;;;;;;;;;;:::i;:::-;;;;;;;;;2912:1;2902:7;:11;2894:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;2954:31;2960:10;2972:12;2954:5;:31::i;:::-;2991:9;3011;3003:23;;:54;196:5;3027:12;:29;;;;:::i;:::-;3003:54;;;;;;;;;;;;;;;;;;;;;;;2991:66;;3071:4;3063:13;;;;;;3104:12;3083:8;:17;3092:7;3083:17;;;;;;;;;;;;:33;;;;;;;:::i;:::-;;;;;;;;3122:22;;;;;;;;;;;:37;;;3160:7;3122:46;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3179:33;3190:7;3199:12;3179:33;;;;;;;:::i;:::-;;;;;;;;2770:447;2687:530;;;:::o;42946:149:1:-;43035:7;43061:11;:18;43073:5;43061:18;;;;;;;;;;;;;;;:27;43080:7;43061:27;;;;;;;;;;;;;;;;43054:34;;42946:149;;;;:::o;2199:484:2:-;2296:22;;;;;;;;;;;:30;;;2327:7;2296:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2282:53;;:10;:53;;;2274:112;;;;;;;;;;;;:::i;:::-;;;;;;;;;2410:1;2400:7;:11;2392:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;2452:22;196:5;2477:9;:26;;;;:::i;:::-;2452:51;;2509:32;2515:9;2526:14;2509:5;:32::i;:::-;2568:14;2548:7;:16;2556:7;2548:16;;;;;;;;;;;;:34;;;;;;;:::i;:::-;;;;;;;;2588:22;;;;;;;;;;;:37;;;2626:7;2588:46;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2645:33;2654:7;2663:14;2645:33;;;;;;;:::i;:::-;;;;;;;;2268:415;2199:484;;:::o;25142:96:1:-;25195:7;25221:10;25214:17;;25142:96;:::o;49416:340::-;49534:1;49517:19;;:5;:19;;;49509:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;49614:1;49595:21;;:7;:21;;;49587:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;49696:6;49666:11;:18;49678:5;49666:18;;;;;;;;;;;;;;;:27;49685:7;49666:27;;;;;;;;;;;;;;;:36;;;;49733:7;49717:32;;49726:5;49717:32;;;49742:6;49717:32;;;;;;:::i;:::-;;;;;;;;49416:340;;;:::o;50037:411::-;50137:24;50164:25;50174:5;50181:7;50164:9;:25::i;:::-;50137:52;;50223:17;50203:16;:37;50199:243;;50284:6;50264:16;:26;;50256:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;50366:51;50375:5;50382:7;50410:6;50391:16;:25;50366:8;:51::i;:::-;50199:243;50127:321;50037:411;;;:::o;46415:788::-;46527:1;46511:18;;:4;:18;;;46503:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;46603:1;46589:16;;:2;:16;;;46581:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;46656:38;46677:4;46683:2;46687:6;46656:20;:38::i;:::-;46705:19;46727:9;:15;46737:4;46727:15;;;;;;;;;;;;;;;;46705:37;;46775:6;46760:11;:21;;46752:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;46890:6;46876:11;:20;46858:9;:15;46868:4;46858:15;;;;;;;;;;;;;;;:38;;;;47090:6;47073:9;:13;47083:2;47073:13;;;;;;;;;;;;;;;;:23;;;;;;;;;;;47137:2;47122:26;;47131:4;47122:26;;;47141:6;47122:26;;;;;;:::i;:::-;;;;;;;;47159:37;47179:4;47185:2;47189:6;47159:19;:37::i;:::-;46493:710;46415:788;;;:::o;48334:659::-;48436:1;48417:21;;:7;:21;;;48409:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;48487:49;48508:7;48525:1;48529:6;48487:20;:49::i;:::-;48547:22;48572:9;:18;48582:7;48572:18;;;;;;;;;;;;;;;;48547:43;;48626:6;48608:14;:24;;48600:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;48743:6;48726:14;:23;48705:9;:18;48715:7;48705:18;;;;;;;;;;;;;;;:44;;;;48858:6;48842:12;;:22;;;;;;;;;;;48916:1;48890:37;;48899:7;48890:37;;;48920:6;48890:37;;;;;;:::i;:::-;;;;;;;;48938:48;48958:7;48975:1;48979:6;48938:19;:48::i;:::-;48399:594;48334:659;;:::o;47479:535::-;47581:1;47562:21;;:7;:21;;;47554:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;47630:49;47659:1;47663:7;47672:6;47630:20;:49::i;:::-;47706:6;47690:12;;:22;;;;;;;:::i;:::-;;;;;;;;47880:6;47858:9;:18;47868:7;47858:18;;;;;;;;;;;;;;;;:28;;;;;;;;;;;47932:7;47911:37;;47928:1;47911:37;;;47941:6;47911:37;;;;;;:::i;:::-;;;;;;;;47959:48;47987:1;47991:7;48000:6;47959:19;:48::i;:::-;47479:535;;:::o;1989:166:2:-;2086:14;:12;:14::i;:::-;2078:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;1989:166;;;:::o;51711:90:1:-;;;;:::o;7:99:3:-;59:6;93:5;87:12;77:22;;7:99;;;:::o;112:169::-;196:11;230:6;225:3;218:19;270:4;265:3;261:14;246:29;;112:169;;;;:::o;287:246::-;368:1;378:113;392:6;389:1;386:13;378:113;;;477:1;472:3;468:11;462:18;458:1;453:3;449:11;442:39;414:2;411:1;407:10;402:15;;378:113;;;525:1;516:6;511:3;507:16;500:27;349:184;287:246;;;:::o;539:102::-;580:6;631:2;627:7;622:2;615:5;611:14;607:28;597:38;;539:102;;;:::o;647:377::-;735:3;763:39;796:5;763:39;:::i;:::-;818:71;882:6;877:3;818:71;:::i;:::-;811:78;;898:65;956:6;951:3;944:4;937:5;933:16;898:65;:::i;:::-;988:29;1010:6;988:29;:::i;:::-;983:3;979:39;972:46;;739:285;647:377;;;;:::o;1030:313::-;1143:4;1181:2;1170:9;1166:18;1158:26;;1230:9;1224:4;1220:20;1216:1;1205:9;1201:17;1194:47;1258:78;1331:4;1322:6;1258:78;:::i;:::-;1250:86;;1030:313;;;;:::o;1430:117::-;1539:1;1536;1529:12;1676:126;1713:7;1753:42;1746:5;1742:54;1731:65;;1676:126;;;:::o;1808:96::-;1845:7;1874:24;1892:5;1874:24;:::i;:::-;1863:35;;1808:96;;;:::o;1910:122::-;1983:24;2001:5;1983:24;:::i;:::-;1976:5;1973:35;1963:63;;2022:1;2019;2012:12;1963:63;1910:122;:::o;2038:139::-;2084:5;2122:6;2109:20;2100:29;;2138:33;2165:5;2138:33;:::i;:::-;2038:139;;;;:::o;2183:77::-;2220:7;2249:5;2238:16;;2183:77;;;:::o;2266:122::-;2339:24;2357:5;2339:24;:::i;:::-;2332:5;2329:35;2319:63;;2378:1;2375;2368:12;2319:63;2266:122;:::o;2394:139::-;2440:5;2478:6;2465:20;2456:29;;2494:33;2521:5;2494:33;:::i;:::-;2394:139;;;;:::o;2539:474::-;2607:6;2615;2664:2;2652:9;2643:7;2639:23;2635:32;2632:119;;;2670:79;;:::i;:::-;2632:119;2790:1;2815:53;2860:7;2851:6;2840:9;2836:22;2815:53;:::i;:::-;2805:63;;2761:117;2917:2;2943:53;2988:7;2979:6;2968:9;2964:22;2943:53;:::i;:::-;2933:63;;2888:118;2539:474;;;;;:::o;3019:90::-;3053:7;3096:5;3089:13;3082:21;3071:32;;3019:90;;;:::o;3115:109::-;3196:21;3211:5;3196:21;:::i;:::-;3191:3;3184:34;3115:109;;:::o;3230:210::-;3317:4;3355:2;3344:9;3340:18;3332:26;;3368:65;3430:1;3419:9;3415:17;3406:6;3368:65;:::i;:::-;3230:210;;;;:::o;3446:118::-;3533:24;3551:5;3533:24;:::i;:::-;3528:3;3521:37;3446:118;;:::o;3570:222::-;3663:4;3701:2;3690:9;3686:18;3678:26;;3714:71;3782:1;3771:9;3767:17;3758:6;3714:71;:::i;:::-;3570:222;;;;:::o;3798:619::-;3875:6;3883;3891;3940:2;3928:9;3919:7;3915:23;3911:32;3908:119;;;3946:79;;:::i;:::-;3908:119;4066:1;4091:53;4136:7;4127:6;4116:9;4112:22;4091:53;:::i;:::-;4081:63;;4037:117;4193:2;4219:53;4264:7;4255:6;4244:9;4240:22;4219:53;:::i;:::-;4209:63;;4164:118;4321:2;4347:53;4392:7;4383:6;4372:9;4368:22;4347:53;:::i;:::-;4337:63;;4292:118;3798:619;;;;;:::o;4423:329::-;4482:6;4531:2;4519:9;4510:7;4506:23;4502:32;4499:119;;;4537:79;;:::i;:::-;4499:119;4657:1;4682:53;4727:7;4718:6;4707:9;4703:22;4682:53;:::i;:::-;4672:63;;4628:117;4423:329;;;;:::o;4758:86::-;4793:7;4833:4;4826:5;4822:16;4811:27;;4758:86;;;:::o;4850:112::-;4933:22;4949:5;4933:22;:::i;:::-;4928:3;4921:35;4850:112;;:::o;4968:214::-;5057:4;5095:2;5084:9;5080:18;5072:26;;5108:67;5172:1;5161:9;5157:17;5148:6;5108:67;:::i;:::-;4968:214;;;;:::o;5188:329::-;5247:6;5296:2;5284:9;5275:7;5271:23;5267:32;5264:119;;;5302:79;;:::i;:::-;5264:119;5422:1;5447:53;5492:7;5483:6;5472:9;5468:22;5447:53;:::i;:::-;5437:63;;5393:117;5188:329;;;;:::o;5523:116::-;5593:21;5608:5;5593:21;:::i;:::-;5586:5;5583:32;5573:60;;5629:1;5626;5619:12;5573:60;5523:116;:::o;5645:133::-;5688:5;5726:6;5713:20;5704:29;;5742:30;5766:5;5742:30;:::i;:::-;5645:133;;;;:::o;5784:323::-;5840:6;5889:2;5877:9;5868:7;5864:23;5860:32;5857:119;;;5895:79;;:::i;:::-;5857:119;6015:1;6040:50;6082:7;6073:6;6062:9;6058:22;6040:50;:::i;:::-;6030:60;;5986:114;5784:323;;;;:::o;6113:60::-;6141:3;6162:5;6155:12;;6113:60;;;:::o;6179:142::-;6229:9;6262:53;6280:34;6289:24;6307:5;6289:24;:::i;:::-;6280:34;:::i;:::-;6262:53;:::i;:::-;6249:66;;6179:142;;;:::o;6327:126::-;6377:9;6410:37;6441:5;6410:37;:::i;:::-;6397:50;;6327:126;;;:::o;6459:156::-;6539:9;6572:37;6603:5;6572:37;:::i;:::-;6559:50;;6459:156;;;:::o;6621:191::-;6738:67;6799:5;6738:67;:::i;:::-;6733:3;6726:80;6621:191;;:::o;6818:282::-;6941:4;6979:2;6968:9;6964:18;6956:26;;6992:101;7090:1;7079:9;7075:17;7066:6;6992:101;:::i;:::-;6818:282;;;;:::o;7106:619::-;7183:6;7191;7199;7248:2;7236:9;7227:7;7223:23;7219:32;7216:119;;;7254:79;;:::i;:::-;7216:119;7374:1;7399:53;7444:7;7435:6;7424:9;7420:22;7399:53;:::i;:::-;7389:63;;7345:117;7501:2;7527:53;7572:7;7563:6;7552:9;7548:22;7527:53;:::i;:::-;7517:63;;7472:118;7629:2;7655:53;7700:7;7691:6;7680:9;7676:22;7655:53;:::i;:::-;7645:63;;7600:118;7106:619;;;;;:::o;7731:474::-;7799:6;7807;7856:2;7844:9;7835:7;7831:23;7827:32;7824:119;;;7862:79;;:::i;:::-;7824:119;7982:1;8007:53;8052:7;8043:6;8032:9;8028:22;8007:53;:::i;:::-;7997:63;;7953:117;8109:2;8135:53;8180:7;8171:6;8160:9;8156:22;8135:53;:::i;:::-;8125:63;;8080:118;7731:474;;;;;:::o;8211:::-;8279:6;8287;8336:2;8324:9;8315:7;8311:23;8307:32;8304:119;;;8342:79;;:::i;:::-;8304:119;8462:1;8487:53;8532:7;8523:6;8512:9;8508:22;8487:53;:::i;:::-;8477:63;;8433:117;8589:2;8615:53;8660:7;8651:6;8640:9;8636:22;8615:53;:::i;:::-;8605:63;;8560:118;8211:474;;;;;:::o;8691:180::-;8739:77;8736:1;8729:88;8836:4;8833:1;8826:15;8860:4;8857:1;8850:15;8877:320;8921:6;8958:1;8952:4;8948:12;8938:22;;9005:1;8999:4;8995:12;9026:18;9016:81;;9082:4;9074:6;9070:17;9060:27;;9016:81;9144:2;9136:6;9133:14;9113:18;9110:38;9107:84;;9163:18;;:::i;:::-;9107:84;8928:269;8877:320;;;:::o;9203:85::-;9248:7;9277:5;9266:16;;9203:85;;;:::o;9294:158::-;9352:9;9385:61;9403:42;9412:32;9438:5;9412:32;:::i;:::-;9403:42;:::i;:::-;9385:61;:::i;:::-;9372:74;;9294:158;;;:::o;9458:147::-;9553:45;9592:5;9553:45;:::i;:::-;9548:3;9541:58;9458:147;;:::o;9611:238::-;9712:4;9750:2;9739:9;9735:18;9727:26;;9763:79;9839:1;9828:9;9824:17;9815:6;9763:79;:::i;:::-;9611:238;;;;:::o;9855:143::-;9912:5;9943:6;9937:13;9928:22;;9959:33;9986:5;9959:33;:::i;:::-;9855:143;;;;:::o;10004:351::-;10074:6;10123:2;10111:9;10102:7;10098:23;10094:32;10091:119;;;10129:79;;:::i;:::-;10091:119;10249:1;10274:64;10330:7;10321:6;10310:9;10306:22;10274:64;:::i;:::-;10264:74;;10220:128;10004:351;;;;:::o;10361:233::-;10501:34;10497:1;10489:6;10485:14;10478:58;10570:16;10565:2;10557:6;10553:15;10546:41;10361:233;:::o;10600:366::-;10742:3;10763:67;10827:2;10822:3;10763:67;:::i;:::-;10756:74;;10839:93;10928:3;10839:93;:::i;:::-;10957:2;10952:3;10948:12;10941:19;;10600:366;;;:::o;10972:419::-;11138:4;11176:2;11165:9;11161:18;11153:26;;11225:9;11219:4;11215:20;11211:1;11200:9;11196:17;11189:47;11253:131;11379:4;11253:131;:::i;:::-;11245:139;;10972:419;;;:::o;11397:289::-;11537:34;11533:1;11525:6;11521:14;11514:58;11606:34;11601:2;11593:6;11589:15;11582:59;11675:3;11670:2;11662:6;11658:15;11651:28;11397:289;:::o;11692:366::-;11834:3;11855:67;11919:2;11914:3;11855:67;:::i;:::-;11848:74;;11931:93;12020:3;11931:93;:::i;:::-;12049:2;12044:3;12040:12;12033:19;;11692:366;;;:::o;12064:419::-;12230:4;12268:2;12257:9;12253:18;12245:26;;12317:9;12311:4;12307:20;12303:1;12292:9;12288:17;12281:47;12345:131;12471:4;12345:131;:::i;:::-;12337:139;;12064:419;;;:::o;12489:180::-;12537:77;12534:1;12527:88;12634:4;12631:1;12624:15;12658:4;12655:1;12648:15;12675:191;12715:3;12734:20;12752:1;12734:20;:::i;:::-;12729:25;;12768:20;12786:1;12768:20;:::i;:::-;12763:25;;12811:1;12808;12804:9;12797:16;;12832:3;12829:1;12826:10;12823:36;;;12839:18;;:::i;:::-;12823:36;12675:191;;;;:::o;12872:293::-;13012:34;13008:1;13000:6;12996:14;12989:58;13081:34;13076:2;13068:6;13064:15;13057:59;13150:7;13145:2;13137:6;13133:15;13126:32;12872:293;:::o;13171:366::-;13313:3;13334:67;13398:2;13393:3;13334:67;:::i;:::-;13327:74;;13410:93;13499:3;13410:93;:::i;:::-;13528:2;13523:3;13519:12;13512:19;;13171:366;;;:::o;13543:419::-;13709:4;13747:2;13736:9;13732:18;13724:26;;13796:9;13790:4;13786:20;13782:1;13771:9;13767:17;13760:47;13824:131;13950:4;13824:131;:::i;:::-;13816:139;;13543:419;;;:::o;13968:233::-;14007:3;14030:24;14048:5;14030:24;:::i;:::-;14021:33;;14076:66;14069:5;14066:77;14063:103;;14146:18;;:::i;:::-;14063:103;14193:1;14186:5;14182:13;14175:20;;13968:233;;;:::o;14207:194::-;14247:4;14267:20;14285:1;14267:20;:::i;:::-;14262:25;;14301:20;14319:1;14301:20;:::i;:::-;14296:25;;14345:1;14342;14338:9;14330:17;;14369:1;14363:4;14360:11;14357:37;;;14374:18;;:::i;:::-;14357:37;14207:194;;;;:::o;14407:180::-;14455:77;14452:1;14445:88;14552:4;14549:1;14542:15;14576:4;14573:1;14566:15;14593:185;14633:1;14650:20;14668:1;14650:20;:::i;:::-;14645:25;;14684:20;14702:1;14684:20;:::i;:::-;14679:25;;14723:1;14713:35;;14728:18;;:::i;:::-;14713:35;14770:1;14767;14763:9;14758:14;;14593:185;;;;:::o;14784:221::-;14924:34;14920:1;14912:6;14908:14;14901:58;14993:4;14988:2;14980:6;14976:15;14969:29;14784:221;:::o;15011:366::-;15153:3;15174:67;15238:2;15233:3;15174:67;:::i;:::-;15167:74;;15250:93;15339:3;15250:93;:::i;:::-;15368:2;15363:3;15359:12;15352:19;;15011:366;;;:::o;15383:419::-;15549:4;15587:2;15576:9;15572:18;15564:26;;15636:9;15630:4;15626:20;15622:1;15611:9;15607:17;15600:47;15664:131;15790:4;15664:131;:::i;:::-;15656:139;;15383:419;;;:::o;15808:224::-;15948:34;15944:1;15936:6;15932:14;15925:58;16017:7;16012:2;16004:6;16000:15;15993:32;15808:224;:::o;16038:366::-;16180:3;16201:67;16265:2;16260:3;16201:67;:::i;:::-;16194:74;;16277:93;16366:3;16277:93;:::i;:::-;16395:2;16390:3;16386:12;16379:19;;16038:366;;;:::o;16410:419::-;16576:4;16614:2;16603:9;16599:18;16591:26;;16663:9;16657:4;16653:20;16649:1;16638:9;16634:17;16627:47;16691:131;16817:4;16691:131;:::i;:::-;16683:139;;16410:419;;;:::o;16835:176::-;16867:1;16884:20;16902:1;16884:20;:::i;:::-;16879:25;;16918:20;16936:1;16918:20;:::i;:::-;16913:25;;16957:1;16947:35;;16962:18;;:::i;:::-;16947:35;17003:1;17000;16996:9;16991:14;;16835:176;;;;:::o;17017:233::-;17157:34;17153:1;17145:6;17141:14;17134:58;17226:16;17221:2;17213:6;17209:15;17202:41;17017:233;:::o;17256:366::-;17398:3;17419:67;17483:2;17478:3;17419:67;:::i;:::-;17412:74;;17495:93;17584:3;17495:93;:::i;:::-;17613:2;17608:3;17604:12;17597:19;;17256:366;;;:::o;17628:419::-;17794:4;17832:2;17821:9;17817:18;17809:26;;17881:9;17875:4;17871:20;17867:1;17856:9;17852:17;17845:47;17909:131;18035:4;17909:131;:::i;:::-;17901:139;;17628:419;;;:::o;18053:180::-;18193:32;18189:1;18181:6;18177:14;18170:56;18053:180;:::o;18239:366::-;18381:3;18402:67;18466:2;18461:3;18402:67;:::i;:::-;18395:74;;18478:93;18567:3;18478:93;:::i;:::-;18596:2;18591:3;18587:12;18580:19;;18239:366;;;:::o;18611:419::-;18777:4;18815:2;18804:9;18800:18;18792:26;;18864:9;18858:4;18854:20;18850:1;18839:9;18835:17;18828:47;18892:131;19018:4;18892:131;:::i;:::-;18884:139;;18611:419;;;:::o;19036:332::-;19157:4;19195:2;19184:9;19180:18;19172:26;;19208:71;19276:1;19265:9;19261:17;19252:6;19208:71;:::i;:::-;19289:72;19357:2;19346:9;19342:18;19333:6;19289:72;:::i;:::-;19036:332;;;;;:::o;19374:233::-;19514:34;19510:1;19502:6;19498:14;19491:58;19583:16;19578:2;19570:6;19566:15;19559:41;19374:233;:::o;19613:366::-;19755:3;19776:67;19840:2;19835:3;19776:67;:::i;:::-;19769:74;;19852:93;19941:3;19852:93;:::i;:::-;19970:2;19965:3;19961:12;19954:19;;19613:366;;;:::o;19985:419::-;20151:4;20189:2;20178:9;20174:18;20166:26;;20238:9;20232:4;20228:20;20224:1;20213:9;20209:17;20202:47;20266:131;20392:4;20266:131;:::i;:::-;20258:139;;19985:419;;;:::o;20410:180::-;20550:32;20546:1;20538:6;20534:14;20527:56;20410:180;:::o;20596:366::-;20738:3;20759:67;20823:2;20818:3;20759:67;:::i;:::-;20752:74;;20835:93;20924:3;20835:93;:::i;:::-;20953:2;20948:3;20944:12;20937:19;;20596:366;;;:::o;20968:419::-;21134:4;21172:2;21161:9;21157:18;21149:26;;21221:9;21215:4;21211:20;21207:1;21196:9;21192:17;21185:47;21249:131;21375:4;21249:131;:::i;:::-;21241:139;;20968:419;;;:::o;21393:410::-;21433:7;21456:20;21474:1;21456:20;:::i;:::-;21451:25;;21490:20;21508:1;21490:20;:::i;:::-;21485:25;;21545:1;21542;21538:9;21567:30;21585:11;21567:30;:::i;:::-;21556:41;;21746:1;21737:7;21733:15;21730:1;21727:22;21707:1;21700:9;21680:83;21657:139;;21776:18;;:::i;:::-;21657:139;21441:362;21393:410;;;;:::o;21809:223::-;21949:34;21945:1;21937:6;21933:14;21926:58;22018:6;22013:2;22005:6;22001:15;21994:31;21809:223;:::o;22038:366::-;22180:3;22201:67;22265:2;22260:3;22201:67;:::i;:::-;22194:74;;22277:93;22366:3;22277:93;:::i;:::-;22395:2;22390:3;22386:12;22379:19;;22038:366;;;:::o;22410:419::-;22576:4;22614:2;22603:9;22599:18;22591:26;;22663:9;22657:4;22653:20;22649:1;22638:9;22634:17;22627:47;22691:131;22817:4;22691:131;:::i;:::-;22683:139;;22410:419;;;:::o;22835:221::-;22975:34;22971:1;22963:6;22959:14;22952:58;23044:4;23039:2;23031:6;23027:15;23020:29;22835:221;:::o;23062:366::-;23204:3;23225:67;23289:2;23284:3;23225:67;:::i;:::-;23218:74;;23301:93;23390:3;23301:93;:::i;:::-;23419:2;23414:3;23410:12;23403:19;;23062:366;;;:::o;23434:419::-;23600:4;23638:2;23627:9;23623:18;23615:26;;23687:9;23681:4;23677:20;23673:1;23662:9;23658:17;23651:47;23715:131;23841:4;23715:131;:::i;:::-;23707:139;;23434:419;;;:::o;23859:179::-;23999:31;23995:1;23987:6;23983:14;23976:55;23859:179;:::o;24044:366::-;24186:3;24207:67;24271:2;24266:3;24207:67;:::i;:::-;24200:74;;24283:93;24372:3;24283:93;:::i;:::-;24401:2;24396:3;24392:12;24385:19;;24044:366;;;:::o;24416:419::-;24582:4;24620:2;24609:9;24605:18;24597:26;;24669:9;24663:4;24659:20;24655:1;24644:9;24640:17;24633:47;24697:131;24823:4;24697:131;:::i;:::-;24689:139;;24416:419;;;:::o;24841:224::-;24981:34;24977:1;24969:6;24965:14;24958:58;25050:7;25045:2;25037:6;25033:15;25026:32;24841:224;:::o;25071:366::-;25213:3;25234:67;25298:2;25293:3;25234:67;:::i;:::-;25227:74;;25310:93;25399:3;25310:93;:::i;:::-;25428:2;25423:3;25419:12;25412:19;;25071:366;;;:::o;25443:419::-;25609:4;25647:2;25636:9;25632:18;25624:26;;25696:9;25690:4;25686:20;25682:1;25671:9;25667:17;25660:47;25724:131;25850:4;25724:131;:::i;:::-;25716:139;;25443:419;;;:::o;25868:222::-;26008:34;26004:1;25996:6;25992:14;25985:58;26077:5;26072:2;26064:6;26060:15;26053:30;25868:222;:::o;26096:366::-;26238:3;26259:67;26323:2;26318:3;26259:67;:::i;:::-;26252:74;;26335:93;26424:3;26335:93;:::i;:::-;26453:2;26448:3;26444:12;26437:19;;26096:366;;;:::o;26468:419::-;26634:4;26672:2;26661:9;26657:18;26649:26;;26721:9;26715:4;26711:20;26707:1;26696:9;26692:17;26685:47;26749:131;26875:4;26749:131;:::i;:::-;26741:139;;26468:419;;;:::o;26893:225::-;27033:34;27029:1;27021:6;27017:14;27010:58;27102:8;27097:2;27089:6;27085:15;27078:33;26893:225;:::o;27124:366::-;27266:3;27287:67;27351:2;27346:3;27287:67;:::i;:::-;27280:74;;27363:93;27452:3;27363:93;:::i;:::-;27481:2;27476:3;27472:12;27465:19;;27124:366;;;:::o;27496:419::-;27662:4;27700:2;27689:9;27685:18;27677:26;;27749:9;27743:4;27739:20;27735:1;27724:9;27720:17;27713:47;27777:131;27903:4;27777:131;:::i;:::-;27769:139;;27496:419;;;:::o;27921:220::-;28061:34;28057:1;28049:6;28045:14;28038:58;28130:3;28125:2;28117:6;28113:15;28106:28;27921:220;:::o;28147:366::-;28289:3;28310:67;28374:2;28369:3;28310:67;:::i;:::-;28303:74;;28386:93;28475:3;28386:93;:::i;:::-;28504:2;28499:3;28495:12;28488:19;;28147:366;;;:::o;28519:419::-;28685:4;28723:2;28712:9;28708:18;28700:26;;28772:9;28766:4;28762:20;28758:1;28747:9;28743:17;28736:47;28800:131;28926:4;28800:131;:::i;:::-;28792:139;;28519:419;;;:::o;28944:221::-;29084:34;29080:1;29072:6;29068:14;29061:58;29153:4;29148:2;29140:6;29136:15;29129:29;28944:221;:::o;29171:366::-;29313:3;29334:67;29398:2;29393:3;29334:67;:::i;:::-;29327:74;;29410:93;29499:3;29410:93;:::i;:::-;29528:2;29523:3;29519:12;29512:19;;29171:366;;;:::o;29543:419::-;29709:4;29747:2;29736:9;29732:18;29724:26;;29796:9;29790:4;29786:20;29782:1;29771:9;29767:17;29760:47;29824:131;29950:4;29824:131;:::i;:::-;29816:139;;29543:419;;;:::o;29968:181::-;30108:33;30104:1;30096:6;30092:14;30085:57;29968:181;:::o;30155:366::-;30297:3;30318:67;30382:2;30377:3;30318:67;:::i;:::-;30311:74;;30394:93;30483:3;30394:93;:::i;:::-;30512:2;30507:3;30503:12;30496:19;;30155:366;;;:::o;30527:419::-;30693:4;30731:2;30720:9;30716:18;30708:26;;30780:9;30774:4;30770:20;30766:1;30755:9;30751:17;30744:47;30808:131;30934:4;30808:131;:::i;:::-;30800:139;;30527:419;;;:::o;30952:232::-;31092:34;31088:1;31080:6;31076:14;31069:58;31161:15;31156:2;31148:6;31144:15;31137:40;30952:232;:::o;31190:366::-;31332:3;31353:67;31417:2;31412:3;31353:67;:::i;:::-;31346:74;;31429:93;31518:3;31429:93;:::i;:::-;31547:2;31542:3;31538:12;31531:19;;31190:366;;;:::o;31562:419::-;31728:4;31766:2;31755:9;31751:18;31743:26;;31815:9;31809:4;31805:20;31801:1;31790:9;31786:17;31779:47;31843:131;31969:4;31843:131;:::i;:::-;31835:139;;31562:419;;;:::o
Swarm Source
ipfs://cc1f1ca317829c4312ec8fe7f8f1184c973b5ffc68db0b9ed6eff72b69358561
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.