Logic address for Authereum account proxies
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 8632149 | 1694 days ago | IN | Create: AuthereumAccount | 0 ETH | 0.21352675 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
AuthereumAccount
Compiler Version
v0.5.8+commit.23d335f2
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-09-27 */ pragma solidity ^0.5.8; contract IERC1271 { function isValidSignature( bytes memory _messageHash, bytes memory _signature) public view returns (bytes4 magicValue); } /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * (.note) This call _does not revert_ if the signature is invalid, or * if the signer is otherwise unable to be retrieved. In those scenarios, * the zero address is returned. * * (.warning) `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise) * be too long), and then calling `toEthSignedMessageHash` on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length if (signature.length != 65) { return (address(0)); } // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return address(0); } if (v != 27 && v != 28) { return address(0); } // If the signature is valid (and not malleable), return the signer address return ecrecover(hash, v, r, s); } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * replicates the behavior of the * [`eth_sign`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign) * JSON-RPC method. * * See `recover`. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. uint256 cs; assembly { cs := extcodesize(address) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes_slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes_slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes_slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes_slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint _start, uint _length ) internal pure returns (bytes memory) { require(_bytes.length >= (_start + _length)); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) { require(_bytes.length >= (_start + 20)); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) { require(_bytes.length >= (_start + 1)); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) { require(_bytes.length >= (_start + 2)); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) { require(_bytes.length >= (_start + 4)); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) { require(_bytes.length >= (_start + 8)); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) { require(_bytes.length >= (_start + 12)); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) { require(_bytes.length >= (_start + 16)); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint(bytes memory _bytes, uint _start) internal pure returns (uint256) { require(_bytes.length >= (_start + 32)); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) { require(_bytes.length >= (_start + 32)); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes_slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } } contract Account is Initializable, IERC1271 { using SafeMath for uint256; using ECDSA for bytes32; using BytesLib for bytes; address[] public authKeysArray; mapping(address => uint256) public authKeysArrayIndex; mapping(address => bool) public authKeys; uint256 public nonce; uint256 public CHAIN_ID; // bytes4(keccak256("isValidSignature(bytes,bytes)") bytes4 constant internal VALID_SIG = 0x20c13b0b; bytes4 constant internal INVALID_SIG = 0xffffffff; event FundsReceived(address indexed sender, uint256 indexed value); event AddedAuthKey(address indexed authKey); event RemovedAuthKey(address indexed authKey); event SwappedAuthKeys(address indexed oldAuthKey, address indexed newAuthKey); // Invalid Sigs event InvalidAuthkey(); event InvalidTransactionDataSigner(); // Invalid Firewalls event OverDailyLimit(); // Invalid Tx event CallFailed(bytes32 encodedData); modifier onlyValidAuthKeyOrSelf { _validateAuthKey(msg.sender); _; } function initialize() public initializer { CHAIN_ID = 1; } function () external payable { emit FundsReceived(msg.sender, msg.value); } /** * Getters */ /// @dev Return the length of the authKeysArray function getAuthKeysArrayLength() public view returns (uint256) { return authKeysArray.length; } /// @dev Get the current nonce of the contract function getNonce() public view returns (uint256) { return nonce; } /** * Public functions */ /// @dev Execute a transaction /// @notice This is to be called directly by an AuthKey /// @param _destination Destination of the transaction /// @param _value Value of the transaction /// @param _data Data of the transaction /// @param _gasLimit Gas limit of the transaction function executeTransaction( address _destination, uint256 _value, bytes memory _data, uint256 _gasLimit ) public onlyValidAuthKeyOrSelf returns (bytes memory) { return _executeTransaction(_destination, _value, _data, _gasLimit); } /// @dev Add an auth key to the list of auth keys /// @param _authKey Address of the auth key to add function addAuthKey(address _authKey) public onlyValidAuthKeyOrSelf { require(!authKeys[_authKey], "Auth key already added"); authKeys[_authKey] = true; authKeysArray.push(_authKey); authKeysArrayIndex[_authKey] = authKeysArray.length - 1; emit AddedAuthKey(_authKey); } /// @dev Add multiple auth keys to the list of auth keys /// @param _authKeys Array of addresses to add to the auth keys list function addMultipleAuthKeys(address[] memory _authKeys) public onlyValidAuthKeyOrSelf { for (uint256 i = 0; i < _authKeys.length; i++) { addAuthKey(_authKeys[i]); } } /// @dev Remove an auth key from the list of auth keys /// @param _authKey Address of the auth key to remove function removeAuthKey(address _authKey) public onlyValidAuthKeyOrSelf { require(authKeys[_authKey], "Auth key not yet added"); require(getAuthKeysArrayLength() > 1, "Cannot remove last auth key"); authKeys[_authKey] = false; _removeAuthKeyFromArray(_authKey); authKeysArrayIndex[_authKey] = 0; emit RemovedAuthKey(_authKey); } /// @dev Remove multiple auth keys to the list of auth keys /// @param _authKeys Array of addresses to remove to the auth keys list function removeMultipleAuthKeys(address[] memory _authKeys) public onlyValidAuthKeyOrSelf { for (uint256 i = 0; i < _authKeys.length; i++) { removeAuthKey(_authKeys[i]); } } /// @dev Swap one authKey for a non-authKey /// @param _oldAuthKey An existing authKey /// @param _newAuthKey A non-existing authKey function swapAuthKeys( address _oldAuthKey, address _newAuthKey ) public onlyValidAuthKeyOrSelf { require(authKeys[_oldAuthKey], "Old auth key does not exist"); require(!authKeys[_newAuthKey], "New auth key already exists"); addAuthKey(_newAuthKey); removeAuthKey(_oldAuthKey); emit SwappedAuthKeys(_oldAuthKey, _newAuthKey); } /// @dev Swap multiple auth keys to the list of auth keys /// @param _oldAuthKeys Array of addresses to remove to the auth keys list /// @param _newAuthKeys Array of addresses to add to the auth keys list function swapMultipleAuthKeys( address[] memory _oldAuthKeys, address[] memory _newAuthKeys ) public { require(_oldAuthKeys.length == _newAuthKeys.length, "Input arrays not equal length"); for (uint256 i = 0; i < _oldAuthKeys.length; i++) { swapAuthKeys(_oldAuthKeys[i], _newAuthKeys[i]); } } function isValidSignature( bytes memory _msg, bytes memory _signatures ) public view returns (bytes4) { if (_signatures.length == 65) { return isValidAuthKeySignature(_msg, _signatures); } else if (_signatures.length == 130) { return isValidLoginKeySignature(_msg, _signatures); } else { revert("Invalid _signatures length"); } } function isValidAuthKeySignature( bytes memory _msg, bytes memory _signature ) public view returns (bytes4) { address authKeyAddress = getEthSignedMessageHash(_msg).recover( _signature ); if(authKeys[authKeyAddress]) { return VALID_SIG; } else { return INVALID_SIG; } } function isValidLoginKeySignature( bytes memory _msg, bytes memory _signatures ) public view returns (bytes4) { bytes memory msgHashSignature = _signatures.slice(0, 65); bytes memory loginKeyAuthorizationSignature = _signatures.slice(65, 65); address loginKeyAddress = getEthSignedMessageHash(_msg).recover( msgHashSignature ); bytes32 loginKeyAuthorizationMessageHash = keccak256(abi.encodePacked( loginKeyAddress )).toEthSignedMessageHash(); address authorizationSigner = loginKeyAuthorizationMessageHash.recover( loginKeyAuthorizationSignature ); if(authKeys[authorizationSigner]) { return VALID_SIG; } else { return INVALID_SIG; } } /** * Internal functions */ /// Remove an authKey from the authKeys array /// @param _authKey authKey to remove function _removeAuthKeyFromArray(address _authKey) internal { uint256 index = authKeysArrayIndex[_authKey]; for (uint256 i = index; i < authKeysArray.length - 1; i++) { authKeysArray[i] = authKeysArray[i + 1]; } delete authKeysArray[authKeysArray.length - 1]; authKeysArray.length--; } /// @dev Validate an authKey /// @param _authKey Address of the auth key to validate function _validateAuthKey(address _authKey) internal view { require(authKeys[_authKey] == true || msg.sender == address(this), "Auth key is invalid"); } /// @dev Validate signatures from an AuthKeyMetaTx /// @param _txDataMessageHash Ethereum signed message of the transaction /// @param _transactionDataSignature Signed tx data function _validateAuthKeyMetaTxSigs( bytes32 _txDataMessageHash, bytes memory _transactionDataSignature ) internal view returns (address) { address transactionDataSigner = _txDataMessageHash.recover(_transactionDataSignature); _validateAuthKey(transactionDataSigner); return transactionDataSigner; } /// @dev Validate signatures from an AuthKeyMetaTx /// @param _txDataMessageHash Ethereum signed message of the transaction /// @param _transactionDataSignature Signed tx data /// @param _loginKeyAuthorizationSignature Signed loginKey function validateLoginKeyMetaTxSigs( bytes32 _txDataMessageHash, bytes memory _transactionDataSignature, bytes memory _loginKeyAuthorizationSignature ) public view returns (address) { address transactionDataSigner = _txDataMessageHash.recover( _transactionDataSignature ); bytes32 loginKeyAuthorizationMessageHash = keccak256(abi.encodePacked( transactionDataSigner )).toEthSignedMessageHash(); address authorizationSigner = loginKeyAuthorizationMessageHash.recover( _loginKeyAuthorizationSignature ); _validateAuthKey(authorizationSigner); return transactionDataSigner; } /// @dev Execute a transaction without a refund /// @notice This is the transaction sent from the CBA /// @param _destination Destination of the transaction /// @param _value Value of the transaction /// @param _data Data of the transaction /// @param _gasLimit Gas limit of the transaction function _executeTransaction( address _destination, uint256 _value, bytes memory _data, uint256 _gasLimit ) internal returns (bytes memory) { (bool success, bytes memory response) = _destination.call.gas(_gasLimit).value(_value)(_data); if (!success) { bytes32 encodedData = _encodeData(nonce, _destination, _value, _data); emit CallFailed(encodedData); } // Increment nonce here so that both relayed and non-relayed calls will increment nonce // Must be incremented after !success data encode in order to encode original nonce nonce++; return response; } /// @dev Execute a transaction with a refund /// @notice This is meant to be used by executeAuthKeyMetaTx when being called /// @notice from a relayer. /// @param _destination Destination of the transaction /// @param _value Value of the transaction /// @param _data Data of the transaction /// @param _gasPrice Gas price of the transaction /// @param _gasLimit Gas limit of the transaction /// @param _startGas Starting gas at the beginning of the transaction function _executeTransactionWithRefund( address _destination, uint256 _value, bytes memory _data, uint256 _gasPrice, uint256 _gasLimit, uint256 _startGas ) internal returns (bytes memory) { bytes memory response = _executeTransaction(_destination, _value, _data, _gasLimit); _issueRefund(_startGas, _gasPrice); return response; } /// @dev Issue a refund /// @param _gasPrice Gas price to use when sending a refund function _issueRefund( uint256 _startGas, uint256 _gasPrice ) internal { uint256 _gasUsed = _startGas.sub(gasleft()); require(_gasUsed.mul(_gasPrice) <= address(this).balance, "Insufficient gas for refund"); msg.sender.transfer(_gasUsed.mul(_gasPrice)); } /// @dev Encode data for a failed transaction /// @param _nonce Nonce of the transaction /// @param _destination Destination of the transaction /// @param _value Value of the transaction /// @param _data Data of the transaction function _encodeData( uint256 _nonce, address _destination, uint256 _value, bytes memory _data ) internal pure returns (bytes32) { return keccak256(abi.encodePacked( _nonce, _destination, _value, _data )); } /// @dev Adds ETH signed message prefix to bytes message and hashes it /// @param _msg the bytes message before adding the prefix /// @return the prefixed and hashed message function getEthSignedMessageHash(bytes memory _msg) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", uint2str(_msg.length), _msg)); } /// @dev Convert uint to string /// @param _num uint to be converted /// @return the string equivalent of the uint function uint2str(uint _num) private pure returns (string memory _uintAsString) { if (_num == 0) { return "0"; } uint i = _num; uint j = _num; uint len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len - 1; while (i != 0) { bstr[k--] = byte(uint8(48 + i % 10)); i /= 10; } return string(bstr); } } contract TransactionLimit is Account { uint256 public dailyLimit; mapping(uint256 => uint256) public dailyLimitTracker; event DailySpendIncrease(uint256 indexed day, uint256 indexed spendIncrease); event DailyLimitChanged(address indexed authKey, uint256 indexed newDailyLimit); function initialize() public initializer { dailyLimit = 10 ether; } /** * Getters */ /// @dev Gets the current day for the contract function getCurrentDay() public view returns (uint256) { return block.timestamp / 86400; } /// @dev Check if a user is within their daily limit function getIsWithinEthDailyTransactionLimit() public view returns (bool) { return getWillBeWithinEthDailyTransactionLimit(0); } /// @dev Check if a user will be within their daily limit after a transaction /// @param _value Value being sent with the current transaction function getWillBeWithinEthDailyTransactionLimit(uint256 _value) public view returns (bool) { uint256 currentDay = getCurrentDay(); uint256 dailySpend = dailyLimitTracker[currentDay] + _value; if (dailySpend <= dailyLimit) { return true; } return false; } /** * Setters */ /// @dev Change the daily limit for a user /// @dev _newDailyLimit New daily limit to set function changeDailyLimit(uint256 _newDailyLimit) public onlyValidAuthKeyOrSelf { dailyLimit = _newDailyLimit; emit DailyLimitChanged(msg.sender, dailyLimit); } /** * Internal functions */ /// @dev Update the tracked balance for daily limit for a user /// @param _value Value being sent with the current transaction function updateEthDailyTransactionLimit(uint256 _value) internal { dailyLimitTracker[getCurrentDay()] += _value; emit DailySpendIncrease(getCurrentDay(), _value); } } contract LoginKeyMetaTxAccount is Account, TransactionLimit { /// @dev Check if a loginKey is valid /// @param transactionDataSigner loginKey that signed the tx data /// @param _loginKeyAuthorizationSignature Signed loginKey function isValidLoginKey( address transactionDataSigner, bytes memory _loginKeyAuthorizationSignature ) public view returns (bool) { bytes32 loginKeyAuthorizationMessageHash = keccak256(abi.encodePacked( transactionDataSigner )).toEthSignedMessageHash(); address authorizationSigner = loginKeyAuthorizationMessageHash.recover( _loginKeyAuthorizationSignature ); return authKeys[authorizationSigner]; } /// @dev Execute an loginKey meta transaction /// @param _destination Destination of the transaction /// @param _data Data of the transaction /// @param _value Value of the transaction /// @param _gasLimit Gas limit of the transaction /// @param _transactionDataSignature Signed tx data /// @param _loginKeyAuthorizationSignature Signed loginKey function executeLoginKeyMetaTx( address _destination, bytes memory _data, uint256 _value, uint256 _gasLimit, bytes memory _transactionDataSignature, bytes memory _loginKeyAuthorizationSignature ) public returns (bytes memory) { uint256 startGas = gasleft(); // This is only in loginKey because authKeys are not restricted by firewalls require(checkFirewall(_value), "Transaction blocked by the firewall"); // Login key cannot upgrade the contract require(checkDestination(_destination), "Login key is not able to upgrade to proxy"); // Update daily limits updateEthDailyTransactionLimit(_value); bytes32 _txDataMessageHash = keccak256(abi.encodePacked( address(this), msg.sig, CHAIN_ID, _destination, _data, _value, nonce, tx.gasprice, _gasLimit )).toEthSignedMessageHash(); address transactionDataSigner = validateLoginKeyMetaTxSigs( _txDataMessageHash, _transactionDataSignature, _loginKeyAuthorizationSignature ); bytes memory response = _executeTransactionWithRefund( _destination, _value, _data, tx.gasprice, _gasLimit, startGas ); return response; } /// @dev Check to see if the transaction passes the firewall /// @param _value Value of the transaction being sent function checkFirewall(uint256 _value) public view returns (bool) { return getWillBeWithinEthDailyTransactionLimit(_value); } /// @dev Check to see if the destination is the proxy admin. /// @notice The login key is not able to upgrade the proxy /// @notice This transaction will throw if an upgrade is attempted /// @param _destination Destination address function checkDestination(address _destination) public view returns (bool) { address proxyAdminAddress; assembly { proxyAdminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103) } return (proxyAdminAddress != _destination); } } contract AuthKeyMetaTxAccount is Account { /// @dev Execute an authKey meta transaction /// @param _destination Destination of the transaction /// @param _data Data of the transaction /// @param _value Value of the transaction /// @param _gasLimit Gas limit of the transaction /// @param _transactionDataSignature Signed tx data function executeAuthKeyMetaTx( address _destination, bytes memory _data, uint256 _value, uint256 _gasLimit, bytes memory _transactionDataSignature ) public returns (bytes memory) { uint256 startGas = gasleft(); bytes32 _txDataMessageHash = keccak256(abi.encodePacked( address(this), msg.sig, CHAIN_ID, _destination, _data, _value, nonce, tx.gasprice, _gasLimit )).toEthSignedMessageHash(); address transactionDataSigner = _validateAuthKeyMetaTxSigs( _txDataMessageHash, _transactionDataSignature ); bytes memory response = _executeTransactionWithRefund( _destination, _value, _data, tx.gasprice, _gasLimit, startGas ); return response; } } /** * AuthereumENSManager interface. */ contract AuthereumENSManager { function register(string calldata _label, address _owner, uint256 _salt) external {} } contract AuthereumAccount is Account, AuthKeyMetaTxAccount, LoginKeyMetaTxAccount, AuthereumENSManager { string constant public authereumVersion = "1.0.0"; /// @dev Initialize the Authereum Account /// @param _authKey authKey that will own this account /// @param _authereumENSManager Address of the Authereum ENS Manager /// @param _label Label of the ENS name /// @param _salt User specific salt function initialize( address _authKey, address _authereumENSManager, string memory _label, uint256 _salt ) public initializer { // Set the CHAIN_ID Account.initialize(); TransactionLimit.initialize(); // Add self as an authKey authKeys[_authKey] = true; authKeysArray.push(_authKey); authKeysArrayIndex[_authKey] = authKeysArray.length - 1; emit AddedAuthKey(_authKey); // Register user in ENS AuthereumENSManager(_authereumENSManager).register(_label, address(this), _salt); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"name":"_destination","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"},{"name":"_gasLimit","type":"uint256"}],"name":"executeTransaction","outputs":[{"name":"","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_authKey","type":"address"}],"name":"addAuthKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_authKeys","type":"address[]"}],"name":"removeMultipleAuthKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authereumVersion","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_value","type":"uint256"}],"name":"getWillBeWithinEthDailyTransactionLimit","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_msg","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"isValidSignature","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentDay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_msg","type":"bytes"},{"name":"_signature","type":"bytes"}],"name":"isValidAuthKeySignature","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_txDataMessageHash","type":"bytes32"},{"name":"_transactionDataSignature","type":"bytes"},{"name":"_loginKeyAuthorizationSignature","type":"bytes"}],"name":"validateLoginKeyMetaTxSigs","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"authKeys","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_oldAuthKeys","type":"address[]"},{"name":"_newAuthKeys","type":"address[]"}],"name":"swapMultipleAuthKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"dailyLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_destination","type":"address"}],"name":"checkDestination","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_destination","type":"address"},{"name":"_data","type":"bytes"},{"name":"_value","type":"uint256"},{"name":"_gasLimit","type":"uint256"},{"name":"_transactionDataSignature","type":"bytes"},{"name":"_loginKeyAuthorizationSignature","type":"bytes"}],"name":"executeLoginKeyMetaTx","outputs":[{"name":"","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN_ID","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_value","type":"uint256"}],"name":"checkFirewall","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_authKey","type":"address"}],"name":"removeAuthKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"dailyLimitTracker","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getIsWithinEthDailyTransactionLimit","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nonce","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_oldAuthKey","type":"address"},{"name":"_newAuthKey","type":"address"}],"name":"swapAuthKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"authKeysArray","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAuthKeysArrayLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newDailyLimit","type":"uint256"}],"name":"changeDailyLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNonce","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_authKey","type":"address"},{"name":"_authereumENSManager","type":"address"},{"name":"_label","type":"string"},{"name":"_salt","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_label","type":"string"},{"name":"_owner","type":"address"},{"name":"_salt","type":"uint256"}],"name":"register","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_msg","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"isValidLoginKeySignature","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_destination","type":"address"},{"name":"_data","type":"bytes"},{"name":"_value","type":"uint256"},{"name":"_gasLimit","type":"uint256"},{"name":"_transactionDataSignature","type":"bytes"}],"name":"executeAuthKeyMetaTx","outputs":[{"name":"","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"authKeysArrayIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_authKeys","type":"address[]"}],"name":"addMultipleAuthKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"transactionDataSigner","type":"address"},{"name":"_loginKeyAuthorizationSignature","type":"bytes"}],"name":"isValidLoginKey","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"day","type":"uint256"},{"indexed":true,"name":"spendIncrease","type":"uint256"}],"name":"DailySpendIncrease","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authKey","type":"address"},{"indexed":true,"name":"newDailyLimit","type":"uint256"}],"name":"DailyLimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"value","type":"uint256"}],"name":"FundsReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authKey","type":"address"}],"name":"AddedAuthKey","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authKey","type":"address"}],"name":"RemovedAuthKey","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldAuthKey","type":"address"},{"indexed":true,"name":"newAuthKey","type":"address"}],"name":"SwappedAuthKeys","type":"event"},{"anonymous":false,"inputs":[],"name":"InvalidAuthkey","type":"event"},{"anonymous":false,"inputs":[],"name":"InvalidTransactionDataSigner","type":"event"},{"anonymous":false,"inputs":[],"name":"OverDailyLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"encodedData","type":"bytes32"}],"name":"CallFailed","type":"event"}]
Contract Creation Code
608060405234801561001057600080fd5b50613e83806100206000396000f3fe6080604052600436106101ee5760003560e01c806388bf3dad1161010d578063cea08621116100a0578063d59e3e981161006f578063d59e3e981461149f578063eba03dae14611650578063ed8fc6b81461185c578063f399f1dd146118c1578063fd54c12214611986576101ee565b8063cea0862114611277578063d087d288146112b2578063d2a200ee146112dd578063d393c871146113ef576101ee565b8063affed0e0116100dc578063affed0e014611135578063b4c2716414611160578063bd1a84ab146111d1578063cd11331e1461124c576101ee565b806388bf3dad146110135780639565389e146110665780639657b809146110b7578063a30e9b1814611106576101ee565b80634c477daf11610185578063691260e011610154578063691260e014610cc557806372cec64114610d2e5780638129fc1c14610fd157806385e1f4d014610fe8576101ee565b80634c477daf1461092f5780635175ca5e14610ad85780635b79818f14610b4157806367eeba0c14610c9a576101ee565b80632016be1c116101c15780632016be1c1461054f57806320c13b0b146105a25780633e6968b61461075357806340914b061461077e576101ee565b806306a41d091461023457806313f8c578146103a95780631704db30146103fa5780631f602092146104bf575b343373ffffffffffffffffffffffffffffffffffffffff167f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f60405160405180910390a3005b34801561024057600080fd5b5061032e6004803603608081101561025757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561029e57600080fd5b8201836020820111156102b057600080fd5b803590602001918460018302840111640100000000831117156102d257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611a86565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036e578082015181840152602081019050610353565b50505050905090810190601f16801561039b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b557600080fd5b506103f8600480360360208110156103cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611aa7565b005b34801561040657600080fd5b506104bd6004803603602081101561041d57600080fd5b810190808035906020019064010000000081111561043a57600080fd5b82018360208201111561044c57600080fd5b8035906020019184602083028401116401000000008311171561046e57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050611cc0565b005b3480156104cb57600080fd5b506104d4611d05565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105145780820151818401526020810190506104f9565b50505050905090810190601f1680156105415780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561055b57600080fd5b506105886004803603602081101561057257600080fd5b8101908080359060200190929190505050611d3e565b604051808215151515815260200191505060405180910390f35b3480156105ae57600080fd5b506106ff600480360360408110156105c557600080fd5b81019080803590602001906401000000008111156105e257600080fd5b8201836020820111156105f457600080fd5b8035906020019184600183028401116401000000008311171561061657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561067957600080fd5b82018360208201111561068b57600080fd5b803590602001918460018302840111640100000000831117156106ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611d85565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561075f57600080fd5b50610768611e31565b6040518082815260200191505060405180910390f35b34801561078a57600080fd5b506108db600480360360408110156107a157600080fd5b81019080803590602001906401000000008111156107be57600080fd5b8201836020820111156107d057600080fd5b803590602001918460018302840111640100000000831117156107f257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561085557600080fd5b82018360208201111561086757600080fd5b8035906020019184600183028401116401000000008311171561088957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611e45565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561093b57600080fd5b50610a966004803603606081101561095257600080fd5b81019080803590602001909291908035906020019064010000000081111561097957600080fd5b82018360208201111561098b57600080fd5b803590602001918460018302840111640100000000831117156109ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610a1057600080fd5b820183602082011115610a2257600080fd5b80359060200191846001830284011164010000000083111715610a4457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611ed9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610ae457600080fd5b50610b2760048036036020811015610afb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f80565b604051808215151515815260200191505060405180910390f35b348015610b4d57600080fd5b50610c9860048036036040811015610b6457600080fd5b8101908080359060200190640100000000811115610b8157600080fd5b820183602082011115610b9357600080fd5b80359060200191846020830284011164010000000083111715610bb557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610c1557600080fd5b820183602082011115610c2757600080fd5b80359060200191846020830284011164010000000083111715610c4957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050611fa0565b005b348015610ca657600080fd5b50610caf612068565b6040518082815260200191505060405180910390f35b348015610cd157600080fd5b50610d1460048036036020811015610ce857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061206e565b604051808215151515815260200191505060405180910390f35b348015610d3a57600080fd5b50610f56600480360360c0811015610d5157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610d8e57600080fd5b820183602082011115610da057600080fd5b80359060200191846001830284011164010000000083111715610dc257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291908035906020019092919080359060200190640100000000811115610e3957600080fd5b820183602082011115610e4b57600080fd5b80359060200191846001830284011164010000000083111715610e6d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ed057600080fd5b820183602082011115610ee257600080fd5b80359060200191846001830284011164010000000083111715610f0457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506120cd565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610f96578082015181840152602081019050610f7b565b50505050905090810190601f168015610fc35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610fdd57600080fd5b50610fe661234d565b005b348015610ff457600080fd5b50610ffd61245b565b6040518082815260200191505060405180910390f35b34801561101f57600080fd5b5061104c6004803603602081101561103657600080fd5b8101908080359060200190929190505050612461565b604051808215151515815260200191505060405180910390f35b34801561107257600080fd5b506110b56004803603602081101561108957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612473565b005b3480156110c357600080fd5b506110f0600480360360208110156110da57600080fd5b81019080803590602001909291905050506126a4565b6040518082815260200191505060405180910390f35b34801561111257600080fd5b5061111b6126bc565b604051808215151515815260200191505060405180910390f35b34801561114157600080fd5b5061114a6126cd565b6040518082815260200191505060405180910390f35b34801561116c57600080fd5b506111cf6004803603604081101561118357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126d3565b005b3480156111dd57600080fd5b5061120a600480360360208110156111f457600080fd5b81019080803590602001909291905050506128cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561125857600080fd5b50611261612907565b6040518082815260200191505060405180910390f35b34801561128357600080fd5b506112b06004803603602081101561129a57600080fd5b8101908080359060200190929190505050612914565b005b3480156112be57600080fd5b506112c761296d565b6040518082815260200191505060405180910390f35b3480156112e957600080fd5b506113ed6004803603608081101561130057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561135d57600080fd5b82018360208201111561136f57600080fd5b8035906020019184600183028401116401000000008311171561139157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050612977565b005b3480156113fb57600080fd5b5061149d6004803603606081101561141257600080fd5b810190808035906020019064010000000081111561142f57600080fd5b82018360208201111561144157600080fd5b8035906020019184600183028401116401000000008311171561146357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612ce3565b005b3480156114ab57600080fd5b506115fc600480360360408110156114c257600080fd5b81019080803590602001906401000000008111156114df57600080fd5b8201836020820111156114f157600080fd5b8035906020019184600183028401116401000000008311171561151357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561157657600080fd5b82018360208201111561158857600080fd5b803590602001918460018302840111640100000000831117156115aa57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612ce9565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561165c57600080fd5b506117e1600480360360a081101561167357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156116b057600080fd5b8201836020820111156116c257600080fd5b803590602001918460018302840111640100000000831117156116e457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803590602001909291908035906020019064010000000081111561175b57600080fd5b82018360208201111561176d57600080fd5b8035906020019184600183028401116401000000008311171561178f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612e34565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611821578082015181840152602081019050611806565b50505050905090810190601f16801561184e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561186857600080fd5b506118ab6004803603602081101561187f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612fed565b6040518082815260200191505060405180910390f35b3480156118cd57600080fd5b50611984600480360360208110156118e457600080fd5b810190808035906020019064010000000081111561190157600080fd5b82018360208201111561191357600080fd5b8035906020019184602083028401116401000000008311171561193557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050613005565b005b34801561199257600080fd5b50611a6c600480360360408110156119a957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156119e657600080fd5b8201836020820111156119f857600080fd5b80359060200191846001830284011164010000000083111715611a1a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061304a565b604051808215151515815260200191505060405180910390f35b6060611a913361311b565b611a9d8585858561321a565b9050949350505050565b611ab03361311b565b603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611b70576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f41757468206b657920616c72656164792061646465640000000000000000000081525060200191505060405180910390fd5b6001603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060338190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600160338054905003603460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508073ffffffffffffffffffffffffffffffffffffffff167f9e46251f3febb4bf40cf64591f0efc1d6ac8a9f0b8900b2adaeb83227757058860405160405180910390a250565b611cc93361311b565b60008090505b8151811015611d0157611cf4828281518110611ce757fe5b6020026020010151612473565b8080600101915050611ccf565b5050565b6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b600080611d49611e31565b905060008360396000848152602001908152602001600020540190506038548111611d7957600192505050611d80565b6000925050505b919050565b6000604182511415611da257611d9b8383611e45565b9050611e2b565b608282511415611dbd57611db68383612ce9565b9050611e2b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f496e76616c6964205f7369676e617475726573206c656e67746800000000000081525060200191505060405180910390fd5b92915050565b6000620151804281611e3f57fe5b04905090565b600080611e6383611e5586613349565b61344890919063ffffffff16565b9050603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611ec7576320c13b0b60e01b915050611ed3565b63ffffffff60e01b9150505b92915050565b600080611eef848661344890919063ffffffff16565b90506000611f5182604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040528051906020012061354c565b90506000611f68858361344890919063ffffffff16565b9050611f738161311b565b8293505050509392505050565b60356020528060005260406000206000915054906101000a900460ff1681565b8051825114612017576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e70757420617272617973206e6f7420657175616c206c656e67746800000081525060200191505060405180910390fd5b60008090505b82518110156120635761205683828151811061203557fe5b602002602001015183838151811061204957fe5b60200260200101516126d3565b808060010191505061201d565b505050565b60385481565b6000807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415915050919050565b606060005a90506120dd86612461565b612132576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613dbd6023913960400191505060405180910390fd5b61213b8861206e565b612190576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180613e2f6029913960400191505060405180910390fd5b612199866135a4565b6000612319306000357fffffffff00000000000000000000000000000000000000000000000000000000166037548c8c8c6036543a8e604051602001808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526004018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140186805190602001908083835b602083106122b95780518252602082019150602081019050602083039250612296565b6001836020036101000a03801982511681845116808217855250505050505090500185815260200184815260200183815260200182815260200199505050505050505050506040516020818303038152906040528051906020012061354c565b90506000612328828787611ed9565b9050606061233a8b8a8c3a8c89613604565b9050809450505050509695505050505050565b600060019054906101000a900460ff168061236c575061236b61362d565b5b8061238357506000809054906101000a900460ff16155b6123d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613e01602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015612428576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b678ac7230489e8000060388190555080156124585760008060016101000a81548160ff0219169083151502179055505b50565b60375481565b600061246c82611d3e565b9050919050565b61247c3361311b565b603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661253b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f41757468206b6579206e6f74207965742061646465640000000000000000000081525060200191505060405180910390fd5b6001612545612907565b116125b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f43616e6e6f742072656d6f7665206c6173742061757468206b6579000000000081525060200191505060405180910390fd5b6000603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506126198161363e565b6000603460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508073ffffffffffffffffffffffffffffffffffffffff167f24a1d50afe4670e7a657fa10322b233e347dc26799afb2d72147a679e693f31f60405160405180910390a250565b60396020528060005260406000206000915090505481565b60006126c86000611d3e565b905090565b60365481565b6126dc3361311b565b603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661279b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4f6c642061757468206b657920646f6573206e6f74206578697374000000000081525060200191505060405180910390fd5b603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561285b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e65772061757468206b657920616c726561647920657869737473000000000081525060200191505060405180910390fd5b61286481611aa7565b61286d82612473565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f084d1bb6d163e102e9e0ca9dcb761e37f325346ac27c1d8bbfb23c105ffba70660405160405180910390a35050565b603381815481106128d857fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000603380549050905090565b61291d3361311b565b806038819055506038543373ffffffffffffffffffffffffffffffffffffffff167fca0b3dabefdbd8c72c0a9cf4a6e9d107da897abf036ef3f3f3b010cdd259415960405160405180910390a350565b6000603654905090565b600060019054906101000a900460ff1680612996575061299561362d565b5b806129ad57506000809054906101000a900460ff16155b612a02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613e01602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015612a52576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b612a5a613792565b612a6261234d565b6001603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060338590806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600160338054905003603460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff167f9e46251f3febb4bf40cf64591f0efc1d6ac8a9f0b8900b2adaeb83227757058860405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff1663d393c8718430856040518463ffffffff1660e01b815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019080838360005b83811015612c55578082015181840152602081019050612c3a565b50505050905090810190601f168015612c825780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015612ca357600080fd5b505af1158015612cb7573d6000803e3d6000fd5b505050508015612cdc5760008060016101000a81548160ff0219169083151502179055505b5050505050565b50505050565b60006060612d0460006041856138999092919063ffffffff16565b90506060612d1e604180866138999092919063ffffffff16565b90506000612d3d83612d2f88613349565b61344890919063ffffffff16565b90506000612d9f82604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040528051906020012061354c565b90506000612db6848361344890919063ffffffff16565b9050603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612e1e576320c13b0b60e01b95505050505050612e2e565b63ffffffff60e01b955050505050505b92915050565b606060005a90506000612fbb306000357fffffffff00000000000000000000000000000000000000000000000000000000166037548b8b8b6036543a8d604051602001808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526004018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140186805190602001908083835b60208310612f5b5780518252602082019150602081019050602083039250612f38565b6001836020036101000a03801982511681845116808217855250505050505090500185815260200184815260200183815260200182815260200199505050505050505050506040516020818303038152906040528051906020012061354c565b90506000612fc98286613925565b90506060612fdb8a898b3a8b89613604565b90508094505050505095945050505050565b60346020528060005260406000206000915090505481565b61300e3361311b565b60008090505b81518110156130465761303982828151811061302c57fe5b6020026020010151611aa7565b8080600101915050613014565b5050565b6000806130ab84604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040528051906020012061354c565b905060006130c2848361344890919063ffffffff16565b9050603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250505092915050565b60011515603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514806131a557503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b613217576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f41757468206b657920697320696e76616c69640000000000000000000000000081525060200191505060405180910390fd5b50565b6060600060608673ffffffffffffffffffffffffffffffffffffffff168487876040518082805190602001908083835b6020831061326d578051825260208201915060208101905060208303925061324a565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381858888f193505050503d80600081146132d0576040519150601f19603f3d011682016040523d82523d6000602084013e6132d5565b606091505b50915091508161332a5760006132ef603654898989613950565b90507fe22e3683fe845a34c5adea424d0beb84895f513ea06745002d9d65f90100591a816040518082815260200191505060405180910390a1505b6036600081548092919060010191905055508092505050949350505050565b60006133558251613a15565b8260405160200180807f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250601a0183805190602001908083835b602083106133b45780518252602082019150602081019050602083039250613391565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061340557805182526020820191506020810190506020830392506133e2565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052805190602001209050919050565b6000604182511461345c5760009050613546565b60008060006020850151925060408501519150606085015160001a90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c11156134b05760009350505050613546565b601b8160ff16141580156134c85750601c8160ff1614155b156134d95760009350505050613546565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015613536573d6000803e3d6000fd5b5050506020604051035193505050505b92915050565b60008160405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c01828152602001915050604051602081830303815290604052805190602001209050919050565b80603960006135b1611e31565b815260200190815260200160002060008282540192505081905550806135d5611e31565b7f60b2ee6a649f9d30c02f548913cf7d99979171db6ea009d4073bfb720040980c60405160405180910390a350565b6060806136138888888761321a565b905061361f8386613b48565b809150509695505050505050565b600080303b90506000811491505090565b6000603460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008190505b60016033805490500381101561373557603360018201815481106136a857fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16603382815481106136e057fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508080600101915050613688565b5060336001603380549050038154811061374b57fe5b9060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055603380548091906001900361378d9190613d6b565b505050565b600060019054906101000a900460ff16806137b157506137b061362d565b5b806137c857506000809054906101000a900460ff16155b61381d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613e01602e913960400191505060405180910390fd5b60008060019054906101000a900460ff16159050801561386d576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b600160378190555080156138965760008060016101000a81548160ff0219169083151502179055505b50565b6060818301845110156138ab57600080fd5b60608215600081146138c857604051915060208201604052613919565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561390657805183526020830192506020810190506138e9565b50868552601f19601f8301166040525050505b50809150509392505050565b60008061393b838561344890919063ffffffff16565b90506139468161311b565b8091505092915050565b600084848484604051602001808581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140183815260200182805190602001908083835b602083106139cd57805182526020820191506020810190506020830392506139aa565b6001836020036101000a038019825116818451168082178552505050505050905001945050505050604051602081830303815290604052805190602001209050949350505050565b60606000821415613a5d576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613b43565b6000829050600083905060005b60008214613a8c578080600101915050600a8281613a8457fe5b049150613a6a565b6060816040519080825280601f01601f191660200182016040528015613ac15781602001600182028038833980820191505090505b50905060006001830390505b60008514613b3a57600a8581613adf57fe5b0660300160f81b82828060019003935081518110613af957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8581613b3257fe5b049450613acd565b81955050505050505b919050565b6000613b5d5a84613c5c90919063ffffffff16565b90503073ffffffffffffffffffffffffffffffffffffffff1631613b8a8383613ce590919063ffffffff16565b1115613bfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496e73756666696369656e742067617320666f7220726566756e64000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc613c2b8484613ce590919063ffffffff16565b9081150290604051600060405180830381858888f19350505050158015613c56573d6000803e3d6000fd5b50505050565b600082821115613cd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600080831415613cf85760009050613d65565b6000828402905082848281613d0957fe5b0414613d60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613de06021913960400191505060405180910390fd5b809150505b92915050565b815481835581811115613d9257818360005260206000209182019101613d919190613d97565b5b505050565b613db991905b80821115613db5576000816000905550600101613d9d565b5090565b9056fe5472616e73616374696f6e20626c6f636b656420627920746865206669726577616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65644c6f67696e206b6579206973206e6f742061626c6520746f207570677261646520746f2070726f7879a165627a7a723058204225d565f04798fc3eb1a58ddd7c204cd2cda325df4bbe551e64a1c05d4eb63c0029
Deployed Bytecode
0x6080604052600436106101ee5760003560e01c806388bf3dad1161010d578063cea08621116100a0578063d59e3e981161006f578063d59e3e981461149f578063eba03dae14611650578063ed8fc6b81461185c578063f399f1dd146118c1578063fd54c12214611986576101ee565b8063cea0862114611277578063d087d288146112b2578063d2a200ee146112dd578063d393c871146113ef576101ee565b8063affed0e0116100dc578063affed0e014611135578063b4c2716414611160578063bd1a84ab146111d1578063cd11331e1461124c576101ee565b806388bf3dad146110135780639565389e146110665780639657b809146110b7578063a30e9b1814611106576101ee565b80634c477daf11610185578063691260e011610154578063691260e014610cc557806372cec64114610d2e5780638129fc1c14610fd157806385e1f4d014610fe8576101ee565b80634c477daf1461092f5780635175ca5e14610ad85780635b79818f14610b4157806367eeba0c14610c9a576101ee565b80632016be1c116101c15780632016be1c1461054f57806320c13b0b146105a25780633e6968b61461075357806340914b061461077e576101ee565b806306a41d091461023457806313f8c578146103a95780631704db30146103fa5780631f602092146104bf575b343373ffffffffffffffffffffffffffffffffffffffff167f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f60405160405180910390a3005b34801561024057600080fd5b5061032e6004803603608081101561025757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561029e57600080fd5b8201836020820111156102b057600080fd5b803590602001918460018302840111640100000000831117156102d257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611a86565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036e578082015181840152602081019050610353565b50505050905090810190601f16801561039b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b557600080fd5b506103f8600480360360208110156103cc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611aa7565b005b34801561040657600080fd5b506104bd6004803603602081101561041d57600080fd5b810190808035906020019064010000000081111561043a57600080fd5b82018360208201111561044c57600080fd5b8035906020019184602083028401116401000000008311171561046e57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050611cc0565b005b3480156104cb57600080fd5b506104d4611d05565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105145780820151818401526020810190506104f9565b50505050905090810190601f1680156105415780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561055b57600080fd5b506105886004803603602081101561057257600080fd5b8101908080359060200190929190505050611d3e565b604051808215151515815260200191505060405180910390f35b3480156105ae57600080fd5b506106ff600480360360408110156105c557600080fd5b81019080803590602001906401000000008111156105e257600080fd5b8201836020820111156105f457600080fd5b8035906020019184600183028401116401000000008311171561061657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561067957600080fd5b82018360208201111561068b57600080fd5b803590602001918460018302840111640100000000831117156106ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611d85565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561075f57600080fd5b50610768611e31565b6040518082815260200191505060405180910390f35b34801561078a57600080fd5b506108db600480360360408110156107a157600080fd5b81019080803590602001906401000000008111156107be57600080fd5b8201836020820111156107d057600080fd5b803590602001918460018302840111640100000000831117156107f257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561085557600080fd5b82018360208201111561086757600080fd5b8035906020019184600183028401116401000000008311171561088957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611e45565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561093b57600080fd5b50610a966004803603606081101561095257600080fd5b81019080803590602001909291908035906020019064010000000081111561097957600080fd5b82018360208201111561098b57600080fd5b803590602001918460018302840111640100000000831117156109ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610a1057600080fd5b820183602082011115610a2257600080fd5b80359060200191846001830284011164010000000083111715610a4457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611ed9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610ae457600080fd5b50610b2760048036036020811015610afb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f80565b604051808215151515815260200191505060405180910390f35b348015610b4d57600080fd5b50610c9860048036036040811015610b6457600080fd5b8101908080359060200190640100000000811115610b8157600080fd5b820183602082011115610b9357600080fd5b80359060200191846020830284011164010000000083111715610bb557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610c1557600080fd5b820183602082011115610c2757600080fd5b80359060200191846020830284011164010000000083111715610c4957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050611fa0565b005b348015610ca657600080fd5b50610caf612068565b6040518082815260200191505060405180910390f35b348015610cd157600080fd5b50610d1460048036036020811015610ce857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061206e565b604051808215151515815260200191505060405180910390f35b348015610d3a57600080fd5b50610f56600480360360c0811015610d5157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610d8e57600080fd5b820183602082011115610da057600080fd5b80359060200191846001830284011164010000000083111715610dc257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291908035906020019092919080359060200190640100000000811115610e3957600080fd5b820183602082011115610e4b57600080fd5b80359060200191846001830284011164010000000083111715610e6d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ed057600080fd5b820183602082011115610ee257600080fd5b80359060200191846001830284011164010000000083111715610f0457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506120cd565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610f96578082015181840152602081019050610f7b565b50505050905090810190601f168015610fc35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610fdd57600080fd5b50610fe661234d565b005b348015610ff457600080fd5b50610ffd61245b565b6040518082815260200191505060405180910390f35b34801561101f57600080fd5b5061104c6004803603602081101561103657600080fd5b8101908080359060200190929190505050612461565b604051808215151515815260200191505060405180910390f35b34801561107257600080fd5b506110b56004803603602081101561108957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612473565b005b3480156110c357600080fd5b506110f0600480360360208110156110da57600080fd5b81019080803590602001909291905050506126a4565b6040518082815260200191505060405180910390f35b34801561111257600080fd5b5061111b6126bc565b604051808215151515815260200191505060405180910390f35b34801561114157600080fd5b5061114a6126cd565b6040518082815260200191505060405180910390f35b34801561116c57600080fd5b506111cf6004803603604081101561118357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126d3565b005b3480156111dd57600080fd5b5061120a600480360360208110156111f457600080fd5b81019080803590602001909291905050506128cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561125857600080fd5b50611261612907565b6040518082815260200191505060405180910390f35b34801561128357600080fd5b506112b06004803603602081101561129a57600080fd5b8101908080359060200190929190505050612914565b005b3480156112be57600080fd5b506112c761296d565b6040518082815260200191505060405180910390f35b3480156112e957600080fd5b506113ed6004803603608081101561130057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561135d57600080fd5b82018360208201111561136f57600080fd5b8035906020019184600183028401116401000000008311171561139157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050612977565b005b3480156113fb57600080fd5b5061149d6004803603606081101561141257600080fd5b810190808035906020019064010000000081111561142f57600080fd5b82018360208201111561144157600080fd5b8035906020019184600183028401116401000000008311171561146357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612ce3565b005b3480156114ab57600080fd5b506115fc600480360360408110156114c257600080fd5b81019080803590602001906401000000008111156114df57600080fd5b8201836020820111156114f157600080fd5b8035906020019184600183028401116401000000008311171561151357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561157657600080fd5b82018360208201111561158857600080fd5b803590602001918460018302840111640100000000831117156115aa57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612ce9565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b34801561165c57600080fd5b506117e1600480360360a081101561167357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156116b057600080fd5b8201836020820111156116c257600080fd5b803590602001918460018302840111640100000000831117156116e457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803590602001909291908035906020019064010000000081111561175b57600080fd5b82018360208201111561176d57600080fd5b8035906020019184600183028401116401000000008311171561178f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612e34565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611821578082015181840152602081019050611806565b50505050905090810190601f16801561184e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561186857600080fd5b506118ab6004803603602081101561187f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612fed565b6040518082815260200191505060405180910390f35b3480156118cd57600080fd5b50611984600480360360208110156118e457600080fd5b810190808035906020019064010000000081111561190157600080fd5b82018360208201111561191357600080fd5b8035906020019184602083028401116401000000008311171561193557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050613005565b005b34801561199257600080fd5b50611a6c600480360360408110156119a957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156119e657600080fd5b8201836020820111156119f857600080fd5b80359060200191846001830284011164010000000083111715611a1a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061304a565b604051808215151515815260200191505060405180910390f35b6060611a913361311b565b611a9d8585858561321a565b9050949350505050565b611ab03361311b565b603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611b70576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f41757468206b657920616c72656164792061646465640000000000000000000081525060200191505060405180910390fd5b6001603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060338190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600160338054905003603460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508073ffffffffffffffffffffffffffffffffffffffff167f9e46251f3febb4bf40cf64591f0efc1d6ac8a9f0b8900b2adaeb83227757058860405160405180910390a250565b611cc93361311b565b60008090505b8151811015611d0157611cf4828281518110611ce757fe5b6020026020010151612473565b8080600101915050611ccf565b5050565b6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b600080611d49611e31565b905060008360396000848152602001908152602001600020540190506038548111611d7957600192505050611d80565b6000925050505b919050565b6000604182511415611da257611d9b8383611e45565b9050611e2b565b608282511415611dbd57611db68383612ce9565b9050611e2b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f496e76616c6964205f7369676e617475726573206c656e67746800000000000081525060200191505060405180910390fd5b92915050565b6000620151804281611e3f57fe5b04905090565b600080611e6383611e5586613349565b61344890919063ffffffff16565b9050603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611ec7576320c13b0b60e01b915050611ed3565b63ffffffff60e01b9150505b92915050565b600080611eef848661344890919063ffffffff16565b90506000611f5182604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040528051906020012061354c565b90506000611f68858361344890919063ffffffff16565b9050611f738161311b565b8293505050509392505050565b60356020528060005260406000206000915054906101000a900460ff1681565b8051825114612017576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f496e70757420617272617973206e6f7420657175616c206c656e67746800000081525060200191505060405180910390fd5b60008090505b82518110156120635761205683828151811061203557fe5b602002602001015183838151811061204957fe5b60200260200101516126d3565b808060010191505061201d565b505050565b60385481565b6000807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415915050919050565b606060005a90506120dd86612461565b612132576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613dbd6023913960400191505060405180910390fd5b61213b8861206e565b612190576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180613e2f6029913960400191505060405180910390fd5b612199866135a4565b6000612319306000357fffffffff00000000000000000000000000000000000000000000000000000000166037548c8c8c6036543a8e604051602001808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526004018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140186805190602001908083835b602083106122b95780518252602082019150602081019050602083039250612296565b6001836020036101000a03801982511681845116808217855250505050505090500185815260200184815260200183815260200182815260200199505050505050505050506040516020818303038152906040528051906020012061354c565b90506000612328828787611ed9565b9050606061233a8b8a8c3a8c89613604565b9050809450505050509695505050505050565b600060019054906101000a900460ff168061236c575061236b61362d565b5b8061238357506000809054906101000a900460ff16155b6123d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613e01602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015612428576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b678ac7230489e8000060388190555080156124585760008060016101000a81548160ff0219169083151502179055505b50565b60375481565b600061246c82611d3e565b9050919050565b61247c3361311b565b603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661253b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f41757468206b6579206e6f74207965742061646465640000000000000000000081525060200191505060405180910390fd5b6001612545612907565b116125b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f43616e6e6f742072656d6f7665206c6173742061757468206b6579000000000081525060200191505060405180910390fd5b6000603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506126198161363e565b6000603460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508073ffffffffffffffffffffffffffffffffffffffff167f24a1d50afe4670e7a657fa10322b233e347dc26799afb2d72147a679e693f31f60405160405180910390a250565b60396020528060005260406000206000915090505481565b60006126c86000611d3e565b905090565b60365481565b6126dc3361311b565b603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661279b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4f6c642061757468206b657920646f6573206e6f74206578697374000000000081525060200191505060405180910390fd5b603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561285b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4e65772061757468206b657920616c726561647920657869737473000000000081525060200191505060405180910390fd5b61286481611aa7565b61286d82612473565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f084d1bb6d163e102e9e0ca9dcb761e37f325346ac27c1d8bbfb23c105ffba70660405160405180910390a35050565b603381815481106128d857fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000603380549050905090565b61291d3361311b565b806038819055506038543373ffffffffffffffffffffffffffffffffffffffff167fca0b3dabefdbd8c72c0a9cf4a6e9d107da897abf036ef3f3f3b010cdd259415960405160405180910390a350565b6000603654905090565b600060019054906101000a900460ff1680612996575061299561362d565b5b806129ad57506000809054906101000a900460ff16155b612a02576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613e01602e913960400191505060405180910390fd5b60008060019054906101000a900460ff161590508015612a52576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b612a5a613792565b612a6261234d565b6001603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060338590806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600160338054905003603460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff167f9e46251f3febb4bf40cf64591f0efc1d6ac8a9f0b8900b2adaeb83227757058860405160405180910390a28373ffffffffffffffffffffffffffffffffffffffff1663d393c8718430856040518463ffffffff1660e01b815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019080838360005b83811015612c55578082015181840152602081019050612c3a565b50505050905090810190601f168015612c825780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015612ca357600080fd5b505af1158015612cb7573d6000803e3d6000fd5b505050508015612cdc5760008060016101000a81548160ff0219169083151502179055505b5050505050565b50505050565b60006060612d0460006041856138999092919063ffffffff16565b90506060612d1e604180866138999092919063ffffffff16565b90506000612d3d83612d2f88613349565b61344890919063ffffffff16565b90506000612d9f82604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040528051906020012061354c565b90506000612db6848361344890919063ffffffff16565b9050603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612e1e576320c13b0b60e01b95505050505050612e2e565b63ffffffff60e01b955050505050505b92915050565b606060005a90506000612fbb306000357fffffffff00000000000000000000000000000000000000000000000000000000166037548b8b8b6036543a8d604051602001808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b8152601401897bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526004018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140186805190602001908083835b60208310612f5b5780518252602082019150602081019050602083039250612f38565b6001836020036101000a03801982511681845116808217855250505050505090500185815260200184815260200183815260200182815260200199505050505050505050506040516020818303038152906040528051906020012061354c565b90506000612fc98286613925565b90506060612fdb8a898b3a8b89613604565b90508094505050505095945050505050565b60346020528060005260406000206000915090505481565b61300e3361311b565b60008090505b81518110156130465761303982828151811061302c57fe5b6020026020010151611aa7565b8080600101915050613014565b5050565b6000806130ab84604051602001808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040528051906020012061354c565b905060006130c2848361344890919063ffffffff16565b9050603560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169250505092915050565b60011515603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151514806131a557503073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b613217576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f41757468206b657920697320696e76616c69640000000000000000000000000081525060200191505060405180910390fd5b50565b6060600060608673ffffffffffffffffffffffffffffffffffffffff168487876040518082805190602001908083835b6020831061326d578051825260208201915060208101905060208303925061324a565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381858888f193505050503d80600081146132d0576040519150601f19603f3d011682016040523d82523d6000602084013e6132d5565b606091505b50915091508161332a5760006132ef603654898989613950565b90507fe22e3683fe845a34c5adea424d0beb84895f513ea06745002d9d65f90100591a816040518082815260200191505060405180910390a1505b6036600081548092919060010191905055508092505050949350505050565b60006133558251613a15565b8260405160200180807f19457468657265756d205369676e6564204d6573736167653a0a000000000000815250601a0183805190602001908083835b602083106133b45780518252602082019150602081019050602083039250613391565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061340557805182526020820191506020810190506020830392506133e2565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052805190602001209050919050565b6000604182511461345c5760009050613546565b60008060006020850151925060408501519150606085015160001a90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c11156134b05760009350505050613546565b601b8160ff16141580156134c85750601c8160ff1614155b156134d95760009350505050613546565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015613536573d6000803e3d6000fd5b5050506020604051035193505050505b92915050565b60008160405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c01828152602001915050604051602081830303815290604052805190602001209050919050565b80603960006135b1611e31565b815260200190815260200160002060008282540192505081905550806135d5611e31565b7f60b2ee6a649f9d30c02f548913cf7d99979171db6ea009d4073bfb720040980c60405160405180910390a350565b6060806136138888888761321a565b905061361f8386613b48565b809150509695505050505050565b600080303b90506000811491505090565b6000603460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008190505b60016033805490500381101561373557603360018201815481106136a857fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16603382815481106136e057fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508080600101915050613688565b5060336001603380549050038154811061374b57fe5b9060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055603380548091906001900361378d9190613d6b565b505050565b600060019054906101000a900460ff16806137b157506137b061362d565b5b806137c857506000809054906101000a900460ff16155b61381d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180613e01602e913960400191505060405180910390fd5b60008060019054906101000a900460ff16159050801561386d576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b600160378190555080156138965760008060016101000a81548160ff0219169083151502179055505b50565b6060818301845110156138ab57600080fd5b60608215600081146138c857604051915060208201604052613919565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561390657805183526020830192506020810190506138e9565b50868552601f19601f8301166040525050505b50809150509392505050565b60008061393b838561344890919063ffffffff16565b90506139468161311b565b8091505092915050565b600084848484604051602001808581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140183815260200182805190602001908083835b602083106139cd57805182526020820191506020810190506020830392506139aa565b6001836020036101000a038019825116818451168082178552505050505050905001945050505050604051602081830303815290604052805190602001209050949350505050565b60606000821415613a5d576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613b43565b6000829050600083905060005b60008214613a8c578080600101915050600a8281613a8457fe5b049150613a6a565b6060816040519080825280601f01601f191660200182016040528015613ac15781602001600182028038833980820191505090505b50905060006001830390505b60008514613b3a57600a8581613adf57fe5b0660300160f81b82828060019003935081518110613af957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8581613b3257fe5b049450613acd565b81955050505050505b919050565b6000613b5d5a84613c5c90919063ffffffff16565b90503073ffffffffffffffffffffffffffffffffffffffff1631613b8a8383613ce590919063ffffffff16565b1115613bfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496e73756666696369656e742067617320666f7220726566756e64000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc613c2b8484613ce590919063ffffffff16565b9081150290604051600060405180830381858888f19350505050158015613c56573d6000803e3d6000fd5b50505050565b600082821115613cd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600080831415613cf85760009050613d65565b6000828402905082848281613d0957fe5b0414613d60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613de06021913960400191505060405180910390fd5b809150505b92915050565b815481835581811115613d9257818360005260206000209182019101613d919190613d97565b5b505050565b613db991905b80821115613db5576000816000905550600101613d9d565b5090565b9056fe5472616e73616374696f6e20626c6f636b656420627920746865206669726577616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65644c6f67696e206b6579206973206e6f742061626c6520746f207570677261646520746f2070726f7879a165627a7a723058204225d565f04798fc3eb1a58ddd7c204cd2cda325df4bbe551e64a1c05d4eb63c0029
Deployed Bytecode Sourcemap
48748:1080:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29700:9;29688:10;29674:36;;;;;;;;;;;;48748:1080;30427:318;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30427:318:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;30427:318:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;30427:318:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;30427:318:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;30427:318:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;30427:318:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;30427:318:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30864:320;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30864:320:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;30864:320:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;32194:209;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32194:209:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;32194:209:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;32194:209:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;32194:209:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;32194:209:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;32194:209:0;;;;;;;;;;;;;;;:::i;:::-;;48860:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48860:49:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;48860:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42788:318;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42788:318:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;42788:318:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;33592:464;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33592:464:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;33592:464:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;33592:464:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;33592:464:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;33592:464:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;33592:464:0;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;33592:464:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;33592:464:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;33592:464:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;33592:464:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;42316:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42316:104:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;34064:415;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34064:415:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;34064:415:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;34064:415:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;34064:415:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;34064:415:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;34064:415:0;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;34064:415:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;34064:415:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;34064:415:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;34064:415:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;36974:758;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36974:758:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;36974:758:0;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;36974:758:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;36974:758:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;36974:758:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;36974:758:0;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;36974:758:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;36974:758:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;36974:758:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;36974:758:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;28700:40;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28700:40:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;28700:40:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;33210:374;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33210:374:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;33210:374:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;33210:374:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;33210:374:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;33210:374:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;33210:374:0;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;33210:374:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;33210:374:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;33210:374:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;33210:374:0;;;;;;;;;;;;;;;:::i;:::-;;41875:25;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41875:25:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;46947:311;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46947:311:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;46947:311:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;44991:1425;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44991:1425:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;44991:1425:0;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;44991:1425:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;44991:1425:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;44991:1425:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;44991:1425:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;44991:1425:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;44991:1425:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;44991:1425:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;44991:1425:0;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;44991:1425:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;44991:1425:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;44991:1425:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;44991:1425:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;44991:1425:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42139:81;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42139:81:0;;;:::i;:::-;;28774:23;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28774:23:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;46549:139;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46549:139:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;46549:139:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;31658:386;;8:9:-1;5:2;;;30:1;27;20:12;5:2;31658:386:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;31658:386:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;41907:52;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41907:52:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;41907:52:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;42486:142;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42486:142:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;28747:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28747:20:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;32559:423;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32559:423:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;32559:423:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28603:30;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28603:30:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;28603:30:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;29816:110;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29816:110:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;43250:183;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43250:183:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;43250:183:0;;;;;;;;;;;;;;;;;:::i;:::-;;29986:81;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29986:81:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;49185:640;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49185:640:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;49185:640:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;49185:640:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;49185:640:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;49185:640:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;49185:640:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;48657:84;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48657:84:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;48657:84:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;48657:84:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;48657:84:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;48657:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;34487:868;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34487:868:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;34487:868:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;34487:868:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;34487:868:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;34487:868:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;34487:868:0;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;34487:868:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;34487:868:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;34487:868:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;34487:868:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;47631:938;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47631:938:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;47631:938:0;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;47631:938:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;47631:938:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;47631:938:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;47631:938:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;47631:938:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;47631:938:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;47631:938:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;47631:938:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;47631:938:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28640:53;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28640:53:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;28640:53:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;31328:203;;8:9:-1;5:2;;;30:1;27;20:12;5:2;31328:203:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;31328:203:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;31328:203:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;31328:203:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;31328:203:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;31328:203:0;;;;;;;;;;;;;;;:::i;:::-;;44066:536;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44066:536:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;44066:536:0;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;44066:536:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;44066:536:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;44066:536:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;44066:536:0;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;30427:318;30641:12;29493:28;29510:10;29493:16;:28::i;:::-;30678:59;30698:12;30712:6;30720:5;30727:9;30678:19;:59::i;:::-;30671:66;;30427:318;;;;;;:::o;30864:320::-;29493:28;29510:10;29493:16;:28::i;:::-;30952:8;:18;30961:8;30952:18;;;;;;;;;;;;;;;;;;;;;;;;;30951:19;30943:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31029:4;31008:8;:18;31017:8;31008:18;;;;;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;31044:13;31063:8;31044:28;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;31044:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31137:1;31114:13;:20;;;;:24;31083:18;:28;31102:8;31083:28;;;;;;;;;;;;;;;:55;;;;31167:8;31154:22;;;;;;;;;;;;30864:320;:::o;32194:209::-;29493:28;29510:10;29493:16;:28::i;:::-;32300:9;32312:1;32300:13;;32295:101;32319:9;:16;32315:1;:20;32295:101;;;32357:27;32371:9;32381:1;32371:12;;;;;;;;;;;;;;32357:13;:27::i;:::-;32337:3;;;;;;;32295:101;;;;32194:209;:::o;48860:49::-;;;;;;;;;;;;;;;;;;;:::o;42788:318::-;42874:4;42891:18;42912:15;:13;:15::i;:::-;42891:36;;42938:18;42991:6;42959:17;:29;42977:10;42959:29;;;;;;;;;;;;:38;42938:59;;43026:10;;43012;:24;43008:68;;43060:4;43053:11;;;;;;43008:68;43093:5;43086:12;;;;42788:318;;;;:::o;33592:464::-;33736:6;33786:2;33764:11;:18;:24;33760:289;;;33812:42;33836:4;33842:11;33812:23;:42::i;:::-;33805:49;;;;33760:289;33898:3;33876:11;:18;:25;33872:177;;;33925:43;33950:4;33956:11;33925:24;:43::i;:::-;33918:50;;;;33872:177;34001:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33592:464;;;;;:::o;42316:104::-;42362:7;42407:5;42389:15;:23;;;;;;42382:30;;42316:104;:::o;34064:415::-;34214:6;34238:22;34263:73;34315:10;34263:29;34287:4;34263:23;:29::i;:::-;:37;;:73;;;;:::i;:::-;34238:98;;34352:8;:24;34361:14;34352:24;;;;;;;;;;;;;;;;;;;;;;;;;34349:123;;;28901:10;34400:9;;34393:16;;;;;34349:123;28957:10;34449:11;;34442:18;;;34064:415;;;;;:::o;36974:758::-;37206:7;37231:29;37263:77;37304:25;37263:18;:26;;:77;;;;:::i;:::-;37231:109;;37353:40;37396:99;37437:21;37406:63;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;37406:63:0;;;37396:74;;;;;;:97;:99::i;:::-;37353:142;;37508:27;37538:97;37593:31;37538:32;:40;;:97;;;;:::i;:::-;37508:127;;37646:37;37663:19;37646:16;:37::i;:::-;37703:21;37696:28;;;;;36974:758;;;;;:::o;28700:40::-;;;;;;;;;;;;;;;;;;;;;;:::o;33210:374::-;33390:12;:19;33367:12;:19;:42;33359:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33459:9;33471:1;33459:13;;33454:123;33478:12;:19;33474:1;:23;33454:123;;;33519:46;33532:12;33545:1;33532:15;;;;;;;;;;;;;;33549:12;33562:1;33549:15;;;;;;;;;;;;;;33519:12;:46::i;:::-;33499:3;;;;;;;33454:123;;;;33210:374;;:::o;41875:25::-;;;;:::o;46947:311::-;47016:4;47033:25;47120:66;47114:73;47093:94;;47237:12;47216:33;;:17;:33;;;;47208:42;;;46947:311;;;:::o;44991:1425::-;45280:12;45310:16;45329:9;45310:28;;45445:21;45459:6;45445:13;:21::i;:::-;45437:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45577:30;45594:12;45577:16;:30::i;:::-;45569:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45698:38;45729:6;45698:30;:38::i;:::-;45749:26;45778:274;45827:4;45847:7;;;;45869:8;;45892:12;45919:5;45939:6;45960:5;;45980:11;46006:9;45788:238;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;45788:238:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;45788:238:0;;;45778:249;;;;;;:272;:274::i;:::-;45749:303;;46065:29;46097:130;46138:18;46158:25;46185:31;46097:26;:130::i;:::-;46065:162;;46240:21;46264:116;46308:12;46322:6;46330:5;46337:11;46350:9;46361:8;46264:29;:116::i;:::-;46240:140;;46400:8;46393:15;;;;;;44991:1425;;;;;;;;:::o;42139:81::-;8539:12;;;;;;;;;;;:31;;;;8555:15;:13;:15::i;:::-;8539:31;:47;;;;8575:11;;;;;;;;;;;8574:12;8539:47;8531:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8646:19;8669:12;;;;;;;;;;;8668:13;8646:35;;8692:14;8688:83;;;8732:4;8717:12;;:19;;;;;;;;;;;;;;;;;;8759:4;8745:11;;:18;;;;;;;;;;;;;;;;;;8688:83;42204:8;42191:10;:21;;;;8793:14;8789:57;;;8833:5;8818:12;;:20;;;;;;;;;;;;;;;;;;8789:57;42139:81;:::o;28774:23::-;;;;:::o;46549:139::-;46609:4;46633:47;46673:6;46633:39;:47::i;:::-;46626:54;;46549:139;;;:::o;31658:386::-;29493:28;29510:10;29493:16;:28::i;:::-;31748:8;:18;31757:8;31748:18;;;;;;;;;;;;;;;;;;;;;;;;;31740:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31839:1;31812:24;:22;:24::i;:::-;:28;31804:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31904:5;31883:8;:18;31892:8;31883:18;;;;;;;;;;;;;;;;:26;;;;;;;;;;;;;;;;;;31920:33;31944:8;31920:23;:33::i;:::-;31995:1;31964:18;:28;31983:8;31964:28;;;;;;;;;;;;;;;:32;;;;32027:8;32012:24;;;;;;;;;;;;31658:386;:::o;41907:52::-;;;;;;;;;;;;;;;;;:::o;42486:142::-;42554:4;42578:42;42618:1;42578:39;:42::i;:::-;42571:49;;42486:142;:::o;28747:20::-;;;;:::o;32559:423::-;29493:28;29510:10;29493:16;:28::i;:::-;32720:8;:21;32729:11;32720:21;;;;;;;;;;;;;;;;;;;;;;;;;32712:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32793:8;:21;32802:11;32793:21;;;;;;;;;;;;;;;;;;;;;;;;;32792:22;32784:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32857:23;32868:11;32857:10;:23::i;:::-;32891:26;32905:11;32891:13;:26::i;:::-;32962:11;32933:41;;32949:11;32933:41;;;;;;;;;;;;32559:423;;:::o;28603:30::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;29816:110::-;29871:7;29898:13;:20;;;;29891:27;;29816:110;:::o;43250:183::-;29493:28;29510:10;29493:16;:28::i;:::-;43354:14;43341:10;:27;;;;43414:10;;43402;43384:41;;;;;;;;;;;;43250:183;:::o;29986:81::-;30027:7;30054:5;;30047:12;;29986:81;:::o;49185:640::-;8539:12;;;;;;;;;;;:31;;;;8555:15;:13;:15::i;:::-;8539:31;:47;;;;8575:11;;;;;;;;;;;8574:12;8539:47;8531:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8646:19;8669:12;;;;;;;;;;;8668:13;8646:35;;8692:14;8688:83;;;8732:4;8717:12;;:19;;;;;;;;;;;;;;;;;;8759:4;8745:11;;:18;;;;;;;;;;;;;;;;;;8688:83;49415:20;:18;:20::i;:::-;49446:29;:27;:29::i;:::-;49544:4;49523:8;:18;49532:8;49523:18;;;;;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;49559:13;49578:8;49559:28;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;49559:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49652:1;49629:13;:20;;;;:24;49598:18;:28;49617:8;49598:28;;;;;;;;;;;;;;;:55;;;;49682:8;49669:22;;;;;;;;;;;;49757:20;49737:50;;;49788:6;49804:4;49811:5;49737:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;49737:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49737:80:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49737:80:0;;;;8793:14;8789:57;;;8833:5;8818:12;;:20;;;;;;;;;;;;;;;;;;8789:57;49185:640;;;;;:::o;48657:84::-;;;;;:::o;34487:868::-;34639:6;34663:29;34695:24;34713:1;34716:2;34695:11;:17;;:24;;;;;:::i;:::-;34663:56;;34730:43;34776:25;34794:2;34798;34776:11;:17;;:25;;;;;:::i;:::-;34730:71;;34814:23;34840:79;34892:16;34840:29;34864:4;34840:23;:29::i;:::-;:37;;:79;;;;:::i;:::-;34814:105;;34932:40;34975:93;35016:15;34985:57;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;34985:57:0;;;34975:68;;;;;;:91;:93::i;:::-;34932:136;;35081:27;35111:96;35166:30;35111:32;:40;;:96;;;;:::i;:::-;35081:126;;35223:8;:29;35232:19;35223:29;;;;;;;;;;;;;;;;;;;;;;;;;35220:128;;;28901:10;35276:9;;35269:16;;;;;;;;;35220:128;28957:10;35325:11;;35318:18;;;;;;;34487:868;;;;;:::o;47631:938::-;47864:12;47894:16;47913:9;47894:28;;47935:26;47964:274;48013:4;48033:7;;;;48055:8;;48078:12;48105:5;48125:6;48146:5;;48166:11;48192:9;47974:238;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;47974:238:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;47974:238:0;;;47964:249;;;;;;:272;:274::i;:::-;47935:303;;48251:29;48283:97;48324:18;48344:25;48283:26;:97::i;:::-;48251:129;;48393:21;48417:116;48461:12;48475:6;48483:5;48490:11;48503:9;48514:8;48417:29;:116::i;:::-;48393:140;;48553:8;48546:15;;;;;;47631:938;;;;;;;:::o;28640:53::-;;;;;;;;;;;;;;;;;:::o;31328:203::-;29493:28;29510:10;29493:16;:28::i;:::-;31431:9;31443:1;31431:13;;31426:98;31450:9;:16;31446:1;:20;31426:98;;;31488:24;31499:9;31509:1;31499:12;;;;;;;;;;;;;;31488:10;:24::i;:::-;31468:3;;;;;;;31426:98;;;;31328:203;:::o;44066:536::-;44241:4;44263:40;44306:99;44347:21;44316:63;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;44316:63:0;;;44306:74;;;;;;:97;:99::i;:::-;44263:142;;44418:27;44448:97;44503:31;44448:32;:40;;:97;;;;:::i;:::-;44418:127;;44565:8;:29;44574:19;44565:29;;;;;;;;;;;;;;;;;;;;;;;;;44558:36;;;;44066:536;;;;:::o;35960:166::-;36059:4;36037:26;;:8;:18;36046:8;36037:18;;;;;;;;;;;;;;;;;;;;;;;;;:26;;;:57;;;;36089:4;36067:27;;:10;:27;;;36037:57;36029:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35960:166;:::o;38061:719::-;38246:12;38277;38291:21;38316:12;:17;;38338:9;38355:6;38363:5;38316:53;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;38316:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;38276:93:0;;;;38387:7;38382:153;;38411:19;38433:47;38445:5;;38452:12;38466:6;38474:5;38433:11;:47::i;:::-;38411:69;;38500:23;38511:11;38500:23;;;;;;;;;;;;;;;;;;38382:153;;38737:5;;:7;;;;;;;;;;;;;38764:8;38757:15;;;;38061:719;;;;;;:::o;40976:200::-;41051:7;41139:21;41148:4;:11;41139:8;:21::i;:::-;41162:4;41088:79;;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;41088:79:0;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;41088:79:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;41088:79:0;;;41078:90;;;;;;41071:97;;40976:200;;;:::o;1430:1930::-;1508:7;1591:2;1571:9;:16;:22;1567:74;;1626:1;1610:19;;;;1567:74;1710:9;1730;1750:7;2002:4;1991:9;1987:20;1981:27;1976:32;;2048:4;2037:9;2033:20;2027:27;2022:32;;2102:4;2091:9;2087:20;2081:27;2078:1;2073:36;2068:41;;3032:66;3027:1;3019:10;;:79;3015:129;;;3130:1;3115:17;;;;;;;3015:129;3165:2;3160:1;:7;;;;:18;;;;;3176:2;3171:1;:7;;;;3160:18;3156:68;;;3210:1;3195:17;;;;;;;3156:68;3328:24;3338:4;3344:1;3347;3350;3328:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3328:24:0;;;;;;;;3321:31;;;;;1430:1930;;;;;:::o;3636:269::-;3705:7;3891:4;3838:58;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3838:58:0;;;3828:69;;;;;;3821:76;;3636:269;;;:::o;43625:187::-;43739:6;43701:17;:34;43719:15;:13;:15::i;:::-;43701:34;;;;;;;;;;;;:44;;;;;;;;;;;43797:6;43780:15;:13;:15::i;:::-;43761:43;;;;;;;;;;43625:187;:::o;39294:443::-;39545:12;39575:21;39599:59;39619:12;39633:6;39641:5;39648:9;39599:19;:59::i;:::-;39575:83;;39669:34;39682:9;39693;39669:12;:34::i;:::-;39721:8;39714:15;;;39294:443;;;;;;;;:::o;8940:476::-;8987:4;9334:10;9380:7;9368:20;9362:26;;9409:1;9403:2;:7;9396:14;;;8940:476;:::o;35505:352::-;35576:13;35592:18;:28;35611:8;35592:28;;;;;;;;;;;;;;;;35576:44;;35638:9;35650:5;35638:17;;35633:125;35684:1;35661:13;:20;;;;:24;35657:1;:28;35633:125;;;35726:13;35744:1;35740;:5;35726:20;;;;;;;;;;;;;;;;;;;;;;;;;35707:13;35721:1;35707:16;;;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;35687:3;;;;;;;35633:125;;;;35777:13;35814:1;35791:13;:20;;;;:24;35777:39;;;;;;;;;;;;;;;;35770:46;;;;;;;;;;;35827:13;:22;;;;;;;;;;;;:::i;:::-;;35505:352;;:::o;29549:72::-;8539:12;;;;;;;;;;;:31;;;;8555:15;:13;:15::i;:::-;8539:31;:47;;;;8575:11;;;;;;;;;;;8574:12;8539:47;8531:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8646:19;8669:12;;;;;;;;;;;8668:13;8646:35;;8692:14;8688:83;;;8732:4;8717:12;;:19;;;;;;;;;;;;;;;;;;8759:4;8745:11;;:18;;;;;;;;;;;;;;;;;;8688:83;29612:1;29601:8;:12;;;;8793:14;8789:57;;;8833:5;8818:12;;:20;;;;;;;;;;;;;;;;;;8789:57;29549:72;:::o;18852:2599::-;18999:12;19064:7;19055:6;:16;19037:6;:13;:35;;19029:44;;;;;;19086:22;19159:7;19152:15;19186:1;19181:2005;;;;21330:4;21324:11;21311:24;;21383:4;21372:9;21368:20;21362:4;21355:34;19145:2259;;19181:2005;19366:4;19360:11;19347:24;;20035:2;20026:7;20022:16;20423:9;20416:17;20410:4;20406:28;20394:9;20383;20379:25;20375:60;20472:7;20468:2;20464:16;20729:6;20715:9;20708:17;20702:4;20698:28;20686:9;20678:6;20674:22;20670:57;20666:70;20500:434;20763:3;20759:2;20756:11;20500:434;;;20911:2;20905:9;20901:2;20894:21;20805:4;20801:2;20797:13;20791:19;;20846:4;20842:2;20838:13;20832:19;;20500:434;;;20504:251;20972:7;20961:9;20954:26;21166:2;21162:7;21157:2;21153;21149:11;21145:25;21139:4;21132:39;19188:1998;;;19145:2259;;21434:9;21427:16;;;18852:2599;;;;;:::o;36325:386::-;36504:7;36529:29;36561:53;36588:25;36561:18;:26;;:53;;;;:::i;:::-;36529:85;;36625:39;36642:21;36625:16;:39::i;:::-;36682:21;36675:28;;;36325:386;;;;:::o;40424:355::-;40612:7;40685:6;40706:12;40733:6;40754:5;40654:116;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;40654:116:0;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;40654:116:0;;;40644:127;;;;;;40637:134;;40424:355;;;;;;:::o;41314:508::-;41365:27;41417:1;41409:4;:9;41405:52;;;41435:10;;;;;;;;;;;;;;;;;;;;;41405:52;41467:6;41476:4;41467:13;;41491:6;41500:4;41491:13;;41515:8;41534:69;41546:1;41541;:6;41534:69;;41564:5;;;;;;;41589:2;41584:7;;;;;;;;;41534:69;;;41613:17;41643:3;41633:14;;;;;;;;;;;;;;;;;;;;;;;;;29:1:-1;21:6;17:14;116:4;104:10;96:6;87:34;147:4;139:6;135:17;125:27;;0:156;41633:14:0;;;;41613:34;;41658:6;41673:1;41667:3;:7;41658:16;;41685:100;41697:1;41692;:6;41685:100;;41747:2;41743:1;:6;;;;;;41738:2;:11;41727:24;;41715:4;41720:3;;;;;;;41715:9;;;;;;;;;;;:36;;;;;;;;;;;41771:2;41766:7;;;;;;;;;41685:100;;;41809:4;41795:19;;;;;;;41314:508;;;;:::o;39839:324::-;39958:16;39977:24;39991:9;39977;:13;;:24;;;;:::i;:::-;39958:43;;40055:4;40047:21;;;40020:23;40033:9;40020:8;:12;;:23;;;;:::i;:::-;:48;;40012:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40111:10;:19;;:44;40131:23;40144:9;40131:8;:12;;:23;;;;:::i;:::-;40111:44;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40111:44:0;39839:324;;;:::o;5200:184::-;5258:7;5291:1;5286;:6;;5278:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5338:9;5354:1;5350;:5;5338:17;;5375:1;5368:8;;;5200:184;;;;:::o;5635:470::-;5693:7;5942:1;5937;:6;5933:47;;;5967:1;5960:8;;;;5933:47;5992:9;6008:1;6004;:5;5992:17;;6037:1;6032;6028;:5;;;;;;:10;6020:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6096:1;6089:8;;;5635:470;;;;;:::o;48748:1080::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
bzzr://4225d565f04798fc3eb1a58ddd7c204cd2cda325df4bbe551e64a1c05d4eb63c
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 25 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.