Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
RootChainManager
Compiler Version
v0.6.6+commit.6c089d02
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-12-01 */ // File: @openzeppelin/contracts/math/SafeMath.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @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) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); 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-contracts/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) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); 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) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/root/RootChainManager/IRootChainManager.sol pragma solidity 0.6.6; interface IRootChainManager { event TokenMapped( address indexed rootToken, address indexed childToken, bytes32 indexed tokenType ); event PredicateRegistered( bytes32 indexed tokenType, address indexed predicateAddress ); function registerPredicate(bytes32 tokenType, address predicateAddress) external; function mapToken( address rootToken, address childToken, bytes32 tokenType ) external; function cleanMapToken( address rootToken, address childToken ) external; function remapToken( address rootToken, address childToken, bytes32 tokenType ) external; function depositEtherFor(address user) external payable; function depositFor( address user, address rootToken, bytes calldata depositData ) external; function exit(bytes calldata inputData) external; } // File: contracts/root/StateSender/IStateSender.sol pragma solidity 0.6.6; interface IStateSender { function syncState(address receiver, bytes calldata data) external; } // File: contracts/root/ICheckpointManager.sol pragma solidity 0.6.6; contract ICheckpointManager { struct HeaderBlock { bytes32 root; uint256 start; uint256 end; uint256 createdAt; address proposer; } /** * @notice mapping of checkpoint header numbers to block details * @dev These checkpoints are submited by plasma contracts */ mapping(uint256 => HeaderBlock) public headerBlocks; } // File: contracts/root/RootChainManager/RootChainManagerStorage.sol pragma solidity 0.6.6; abstract contract RootChainManagerStorage { mapping(bytes32 => address) public typeToPredicate; mapping(address => address) public rootToChildToken; mapping(address => address) public childToRootToken; mapping(address => bytes32) public tokenToType; mapping(bytes32 => bool) public processedExits; IStateSender internal _stateSender; ICheckpointManager internal _checkpointManager; address public childChainManagerAddress; } // File: contracts/lib/RLPReader.sol /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns * https://github.com/hamdiallam/Solidity-RLP/blob/e681e25a376dbd5426b509380bc03446f05d0f97/contracts/RLPReader.sol */ pragma solidity 0.6.6; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint len; uint memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint ptr = self.nextPtr; uint itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param the RLP item. */ function rlpLen(RLPItem memory item) internal pure returns (uint) { return item.len; } /* * @param the RLP item. * @return (memPtr, len) pair: location of the item's payload in memory. */ function payloadLocation(RLPItem memory item) internal pure returns (uint, uint) { uint offset = _payloadOffset(item.memPtr); uint memPtr = item.memPtr + offset; uint len = item.len - offset; // data length return (memPtr, len); } /* * @param the RLP item. */ function payloadLen(RLPItem memory item) internal pure returns (uint) { (, uint len) = payloadLocation(item); return len; } /* * @param the RLP item containing the encoded list. */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint memPtr = item.memPtr + _payloadOffset(item.memPtr); uint dataLen; for (uint i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint memPtr, uint len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte except "0x80" is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint result; uint memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } // SEE Github Issue #5. // Summary: Most commonly used RLP libraries (i.e Geth) will encode // "0" as "0x80" instead of as "0". We handle this edge case explicitly // here. if (result == 0 || result == STRING_SHORT_START) { return false; } else { return true; } } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(toUint(item)); } function toUint(RLPItem memory item) internal pure returns (uint) { require(item.len > 0 && item.len <= 33); (uint memPtr, uint len) = payloadLocation(item); uint result; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint) { // one byte prefix require(item.len == 33); uint result; uint memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); (uint memPtr, uint len) = payloadLocation(item); bytes memory result = new bytes(len); uint destPtr; assembly { destPtr := add(0x20, result) } copy(memPtr, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint) { if (item.len == 0) return 0; uint count = 0; uint currPtr = item.memPtr + _payloadOffset(item.memPtr); uint endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint memPtr) private pure returns (uint) { uint itemLen; uint byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint memPtr) private pure returns (uint) { uint byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy(uint src, uint dest, uint len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len > 0) { // left over bytes. Mask is used to remove unwanted bytes from the word uint mask = 256 ** (WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } } } // File: contracts/lib/ExitPayloadReader.sol pragma solidity 0.6.6; library ExitPayloadReader { using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; uint8 constant WORD_SIZE = 32; struct ExitPayload { RLPReader.RLPItem[] data; } struct Receipt { RLPReader.RLPItem[] data; bytes raw; uint256 logIndex; } struct Log { RLPReader.RLPItem data; RLPReader.RLPItem[] list; } struct LogTopics { RLPReader.RLPItem[] data; } // copy paste of private copy() from RLPReader to avoid changing of existing contracts function copy(uint src, uint dest, uint len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } // left over bytes. Mask is used to remove unwanted bytes from the word uint mask = 256 ** (WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) { RLPReader.RLPItem[] memory payloadData = data .toRlpItem() .toList(); return ExitPayload(payloadData); } function getHeaderNumber(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[0].toUint(); } function getBlockProof(ExitPayload memory payload) internal pure returns(bytes memory) { return payload.data[1].toBytes(); } function getBlockNumber(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[2].toUint(); } function getBlockTime(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[3].toUint(); } function getTxRoot(ExitPayload memory payload) internal pure returns(bytes32) { return bytes32(payload.data[4].toUint()); } function getReceiptRoot(ExitPayload memory payload) internal pure returns(bytes32) { return bytes32(payload.data[5].toUint()); } function getReceipt(ExitPayload memory payload) internal pure returns(Receipt memory receipt) { receipt.raw = payload.data[6].toBytes(); RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem(); if (receiptItem.isList()) { // legacy tx receipt.data = receiptItem.toList(); } else { // pop first byte before parsting receipt bytes memory typedBytes = receipt.raw; bytes memory result = new bytes(typedBytes.length - 1); uint256 srcPtr; uint256 destPtr; assembly { srcPtr := add(33, typedBytes) destPtr := add(0x20, result) } copy(srcPtr, destPtr, result.length); receipt.data = result.toRlpItem().toList(); } receipt.logIndex = getReceiptLogIndex(payload); return receipt; } function getReceiptProof(ExitPayload memory payload) internal pure returns(bytes memory) { return payload.data[7].toBytes(); } function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns(bytes memory) { return payload.data[8].toBytes(); } function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[8].toUint(); } function getReceiptLogIndex(ExitPayload memory payload) internal pure returns(uint256) { return payload.data[9].toUint(); } // Receipt methods function toBytes(Receipt memory receipt) internal pure returns(bytes memory) { return receipt.raw; } function getLog(Receipt memory receipt) internal pure returns(Log memory) { RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex]; return Log(logData, logData.toList()); } // Log methods function getEmitter(Log memory log) internal pure returns(address) { return RLPReader.toAddress(log.list[0]); } function getTopics(Log memory log) internal pure returns(LogTopics memory) { return LogTopics(log.list[1].toList()); } function getData(Log memory log) internal pure returns(bytes memory) { return log.list[2].toBytes(); } function toRlpBytes(Log memory log) internal pure returns(bytes memory) { return log.data.toRlpBytes(); } // LogTopics methods function getField(LogTopics memory topics, uint256 index) internal pure returns(RLPReader.RLPItem memory) { return topics.data[index]; } } // File: contracts/lib/MerklePatriciaProof.sol /* * @title MerklePatriciaVerifier * @author Sam Mayo ([email protected]) * * @dev Library for verifing merkle patricia proofs. */ pragma solidity 0.6.6; library MerklePatriciaProof { /* * @dev Verifies a merkle patricia proof. * @param value The terminating value in the trie. * @param encodedPath The path in the trie leading to value. * @param rlpParentNodes The rlp encoded stack of nodes. * @param root The root hash of the trie. * @return The boolean validity of the proof. */ function verify( bytes memory value, bytes memory encodedPath, bytes memory rlpParentNodes, bytes32 root ) internal pure returns (bool) { RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes); RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item); bytes memory currentNode; RLPReader.RLPItem[] memory currentNodeList; bytes32 nodeKey = root; uint256 pathPtr = 0; bytes memory path = _getNibbleArray(encodedPath); if (path.length == 0) { return false; } for (uint256 i = 0; i < parentNodes.length; i++) { if (pathPtr > path.length) { return false; } currentNode = RLPReader.toRlpBytes(parentNodes[i]); if (nodeKey != keccak256(currentNode)) { return false; } currentNodeList = RLPReader.toList(parentNodes[i]); if (currentNodeList.length == 17) { if (pathPtr == path.length) { if ( keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value) ) { return true; } else { return false; } } uint8 nextPathNibble = uint8(path[pathPtr]); if (nextPathNibble > 16) { return false; } nodeKey = bytes32( RLPReader.toUintStrict(currentNodeList[nextPathNibble]) ); pathPtr += 1; } else if (currentNodeList.length == 2) { uint256 traversed = _nibblesToTraverse( RLPReader.toBytes(currentNodeList[0]), path, pathPtr ); if (pathPtr + traversed == path.length) { //leaf node if ( keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value) ) { return true; } else { return false; } } //extension node if (traversed == 0) { return false; } pathPtr += traversed; nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1])); } else { return false; } } return false; // default } function _nibblesToTraverse( bytes memory encodedPartialPath, bytes memory path, uint256 pathPtr ) private pure returns (uint256) { uint256 len = 0; // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath // and slicedPath have elements that are each one hex character (1 nibble) bytes memory partialPath = _getNibbleArray(encodedPartialPath); bytes memory slicedPath = new bytes(partialPath.length); // pathPtr counts nibbles in path // partialPath.length is a number of nibbles for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) { bytes1 pathNibble = path[i]; slicedPath[i - pathPtr] = pathNibble; } if (keccak256(partialPath) == keccak256(slicedPath)) { len = partialPath.length; } else { len = 0; } return len; } // bytes b must be hp encoded function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) { bytes memory nibbles = ""; if (b.length > 0) { uint8 offset; uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b)); if (hpNibble == 1 || hpNibble == 3) { nibbles = new bytes(b.length * 2 - 1); bytes1 oddNibble = _getNthNibbleOfBytes(1, b); nibbles[0] = oddNibble; offset = 1; } else { nibbles = new bytes(b.length * 2 - 2); offset = 0; } for (uint256 i = offset; i < nibbles.length; i++) { nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b); } } return nibbles; } function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) { return bytes1( n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10 ); } } // File: contracts/lib/Merkle.sol pragma solidity 0.6.6; library Merkle { function checkMembership( bytes32 leaf, uint256 index, bytes32 rootHash, bytes memory proof ) internal pure returns (bool) { require(proof.length % 32 == 0, "Invalid proof length"); uint256 proofHeight = proof.length / 32; // Proof of size n means, height of the tree is n+1. // In a tree of height n+1, max #leafs possible is 2 ^ n require(index < 2 ** proofHeight, "Leaf index is too big"); bytes32 proofElement; bytes32 computedHash = leaf; for (uint256 i = 32; i <= proof.length; i += 32) { assembly { proofElement := mload(add(proof, i)) } if (index % 2 == 0) { computedHash = keccak256( abi.encodePacked(computedHash, proofElement) ); } else { computedHash = keccak256( abi.encodePacked(proofElement, computedHash) ); } index = index / 2; } return computedHash == rootHash; } } // File: contracts/root/TokenPredicates/ITokenPredicate.sol pragma solidity 0.6.6; /// @title Token predicate interface for all pos portal predicates /// @notice Abstract interface that defines methods for custom predicates interface ITokenPredicate { /** * @notice Deposit tokens into pos portal * @dev When `depositor` deposits tokens into pos portal, tokens get locked into predicate contract. * @param depositor Address who wants to deposit tokens * @param depositReceiver Address (address) who wants to receive tokens on side chain * @param rootToken Token which gets deposited * @param depositData Extra data for deposit (amount for ERC20, token id for ERC721 etc.) [ABI encoded] */ function lockTokens( address depositor, address depositReceiver, address rootToken, bytes calldata depositData ) external; /** * @notice Validates and processes exit while withdraw process * @dev Validates exit log emitted on sidechain. Reverts if validation fails. * @dev Processes withdraw based on custom logic. Example: transfer ERC20/ERC721, mint ERC721 if mintable withdraw * @param rootToken Token which gets withdrawn * @param logRLPList Valid sidechain log for data like amount, token id etc. */ function exitTokens( address rootToken, bytes calldata logRLPList ) external; } // File: contracts/common/Initializable.sol pragma solidity 0.6.6; contract Initializable { bool inited = false; modifier initializer() { require(!inited, "already inited"); _; inited = true; } } // File: contracts/common/EIP712Base.sol pragma solidity 0.6.6; contract EIP712Base is Initializable { struct EIP712Domain { string name; string version; address verifyingContract; bytes32 salt; } string constant public ERC712_VERSION = "1"; bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256( bytes( "EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)" ) ); bytes32 internal domainSeperator; // supposed to be called once while initializing. // one of the contractsa that inherits this contract follows proxy pattern // so it is not possible to do this in a constructor function _initializeEIP712( string memory name ) internal initializer { _setDomainSeperator(name); } function _setDomainSeperator(string memory name) internal { domainSeperator = keccak256( abi.encode( EIP712_DOMAIN_TYPEHASH, keccak256(bytes(name)), keccak256(bytes(ERC712_VERSION)), address(this), bytes32(getChainId()) ) ); } function getDomainSeperator() public view returns (bytes32) { return domainSeperator; } function getChainId() public pure returns (uint256) { uint256 id; assembly { id := chainid() } return id; } /** * Accept message hash and returns hash message in EIP712 compatible form * So that it can be used to recover signer from signature signed using EIP712 formatted data * https://eips.ethereum.org/EIPS/eip-712 * "\\x19" makes the encoding deterministic * "\\x01" is the version byte to make it compatible to EIP-191 */ function toTypedMessageHash(bytes32 messageHash) internal view returns (bytes32) { return keccak256( abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash) ); } } // File: contracts/common/NativeMetaTransaction.sol pragma solidity 0.6.6; contract NativeMetaTransaction is EIP712Base { using SafeMath for uint256; bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256( bytes( "MetaTransaction(uint256 nonce,address from,bytes functionSignature)" ) ); event MetaTransactionExecuted( address indexed userAddress, address payable indexed relayerAddress, bytes functionSignature ); mapping(address => uint256) nonces; /* * Meta transaction structure. * No point of including value field here as if user is doing value transfer then he has the funds to pay for gas * He should call the desired function directly in that case. */ struct MetaTransaction { uint256 nonce; address from; bytes functionSignature; } function executeMetaTransaction( address userAddress, bytes calldata functionSignature, bytes32 sigR, bytes32 sigS, uint8 sigV ) external payable returns (bytes memory) { MetaTransaction memory metaTx = MetaTransaction({ nonce: nonces[userAddress], from: userAddress, functionSignature: functionSignature }); require( verify(userAddress, metaTx, sigR, sigS, sigV), "Signer and signature do not match" ); // increase nonce for user (to avoid re-use) ++nonces[userAddress]; emit MetaTransactionExecuted( userAddress, msg.sender, functionSignature ); // Append userAddress and relayer address at the end to extract it from calling context (bool success, bytes memory returnData) = address(this).call( abi.encodePacked(functionSignature, userAddress) ); require(success, "Function call not successful"); return returnData; } function getNonce(address user) external view returns (uint256 nonce) { nonce = nonces[user]; } function hashMetaTransaction(MetaTransaction memory metaTx) internal pure returns (bytes32) { return keccak256( abi.encode( META_TRANSACTION_TYPEHASH, metaTx.nonce, metaTx.from, keccak256(metaTx.functionSignature) ) ); } function verify( address signer, MetaTransaction memory metaTx, bytes32 sigR, bytes32 sigS, uint8 sigV ) internal view returns (bool) { require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER"); return signer == ecrecover( toTypedMessageHash(hashMetaTransaction(metaTx)), sigV, sigR, sigS ); } } // File: @openzeppelin/contracts/utils/EnumerableSet.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256` * (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(value))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(value))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(value))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File: @openzeppelin/contracts/utils/Address.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.2; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/GSN/Context.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts/access/AccessControl.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address; struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } } // File: contracts/common/AccessControlMixin.sol pragma solidity 0.6.6; contract AccessControlMixin is AccessControl { string private _revertMsg; function _setupContractId(string memory contractId) internal { _revertMsg = string(abi.encodePacked(contractId, ": INSUFFICIENT_PERMISSIONS")); } modifier only(bytes32 role) { require( hasRole(role, _msgSender()), _revertMsg ); _; } } // File: contracts/common/ContextMixin.sol pragma solidity 0.6.6; abstract contract ContextMixin { function msgSender() internal view returns (address payable sender) { if (msg.sender == address(this)) { bytes memory array = msg.data; uint256 index = msg.data.length; assembly { // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those. sender := and( mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff ) } } else { sender = msg.sender; } return sender; } } // File: contracts/root/RootChainManager/RootChainManager.sol pragma solidity 0.6.6; contract RootChainManager is IRootChainManager, Initializable, AccessControl, // included to match old storage layout while upgrading RootChainManagerStorage, // created to match old storage layout while upgrading AccessControlMixin, NativeMetaTransaction, ContextMixin { using ExitPayloadReader for bytes; using ExitPayloadReader for ExitPayloadReader.ExitPayload; using ExitPayloadReader for ExitPayloadReader.Log; using ExitPayloadReader for ExitPayloadReader.Receipt; using Merkle for bytes32; using SafeMath for uint256; // maybe DEPOSIT and MAP_TOKEN can be reduced to bytes4 bytes32 public constant DEPOSIT = keccak256("DEPOSIT"); bytes32 public constant MAP_TOKEN = keccak256("MAP_TOKEN"); address public constant ETHER_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; bytes32 public constant MAPPER_ROLE = keccak256("MAPPER_ROLE"); function _msgSender() internal override view returns (address payable sender) { return ContextMixin.msgSender(); } /** * @notice Deposit ether by directly sending to the contract * The account sending ether receives WETH on child chain */ receive() external payable { _depositEtherFor(_msgSender()); } /** * @notice Initialize the contract after it has been proxified * @dev meant to be called once immediately after deployment * @param _owner the account that should be granted admin role */ function initialize( address _owner ) external initializer { _initializeEIP712("RootChainManager"); _setupContractId("RootChainManager"); _setupRole(DEFAULT_ADMIN_ROLE, _owner); _setupRole(MAPPER_ROLE, _owner); } // adding seperate function setupContractId since initialize is already called with old implementation function setupContractId() external only(DEFAULT_ADMIN_ROLE) { _setupContractId("RootChainManager"); } // adding seperate function initializeEIP712 since initialize is already called with old implementation function initializeEIP712() external only(DEFAULT_ADMIN_ROLE) { _setDomainSeperator("RootChainManager"); } /** * @notice Set the state sender, callable only by admins * @dev This should be the state sender from plasma contracts * It is used to send bytes from root to child chain * @param newStateSender address of state sender contract */ function setStateSender(address newStateSender) external only(DEFAULT_ADMIN_ROLE) { require(newStateSender != address(0), "RootChainManager: BAD_NEW_STATE_SENDER"); _stateSender = IStateSender(newStateSender); } /** * @notice Get the address of contract set as state sender * @return The address of state sender contract */ function stateSenderAddress() external view returns (address) { return address(_stateSender); } /** * @notice Set the checkpoint manager, callable only by admins * @dev This should be the plasma contract responsible for keeping track of checkpoints * @param newCheckpointManager address of checkpoint manager contract */ function setCheckpointManager(address newCheckpointManager) external only(DEFAULT_ADMIN_ROLE) { require(newCheckpointManager != address(0), "RootChainManager: BAD_NEW_CHECKPOINT_MANAGER"); _checkpointManager = ICheckpointManager(newCheckpointManager); } /** * @notice Get the address of contract set as checkpoint manager * @return The address of checkpoint manager contract */ function checkpointManagerAddress() external view returns (address) { return address(_checkpointManager); } /** * @notice Set the child chain manager, callable only by admins * @dev This should be the contract responsible to receive deposit bytes on child chain * @param newChildChainManager address of child chain manager contract */ function setChildChainManagerAddress(address newChildChainManager) external only(DEFAULT_ADMIN_ROLE) { require(newChildChainManager != address(0x0), "RootChainManager: INVALID_CHILD_CHAIN_ADDRESS"); childChainManagerAddress = newChildChainManager; } /** * @notice Register a token predicate address against its type, callable only by ADMIN * @dev A predicate is a contract responsible to process the token specific logic while locking or exiting tokens * @param tokenType bytes32 unique identifier for the token type * @param predicateAddress address of token predicate address */ function registerPredicate(bytes32 tokenType, address predicateAddress) external override only(DEFAULT_ADMIN_ROLE) { typeToPredicate[tokenType] = predicateAddress; emit PredicateRegistered(tokenType, predicateAddress); } /** * @notice Map a token to enable its movement via the PoS Portal, callable only by mappers * @param rootToken address of token on root chain * @param childToken address of token on child chain * @param tokenType bytes32 unique identifier for the token type */ function mapToken( address rootToken, address childToken, bytes32 tokenType ) external override only(MAPPER_ROLE) { // explicit check if token is already mapped to avoid accidental remaps require( rootToChildToken[rootToken] == address(0) && childToRootToken[childToken] == address(0), "RootChainManager: ALREADY_MAPPED" ); _mapToken(rootToken, childToken, tokenType); } /** * @notice Clean polluted token mapping * @param rootToken address of token on root chain. Since rename token was introduced later stage, * clean method is used to clean pollulated mapping */ function cleanMapToken( address rootToken, address childToken ) external override only(DEFAULT_ADMIN_ROLE) { rootToChildToken[rootToken] = address(0); childToRootToken[childToken] = address(0); tokenToType[rootToken] = bytes32(0); emit TokenMapped(rootToken, childToken, tokenToType[rootToken]); } /** * @notice Remap a token that has already been mapped, properly cleans up old mapping * Callable only by ADMIN * @param rootToken address of token on root chain * @param childToken address of token on child chain * @param tokenType bytes32 unique identifier for the token type */ function remapToken( address rootToken, address childToken, bytes32 tokenType ) external override only(DEFAULT_ADMIN_ROLE) { // cleanup old mapping address oldChildToken = rootToChildToken[rootToken]; address oldRootToken = childToRootToken[childToken]; if (rootToChildToken[oldRootToken] != address(0)) { rootToChildToken[oldRootToken] = address(0); tokenToType[oldRootToken] = bytes32(0); } if (childToRootToken[oldChildToken] != address(0)) { childToRootToken[oldChildToken] = address(0); } _mapToken(rootToken, childToken, tokenType); } function _mapToken( address rootToken, address childToken, bytes32 tokenType ) private { require( typeToPredicate[tokenType] != address(0x0), "RootChainManager: TOKEN_TYPE_NOT_SUPPORTED" ); rootToChildToken[rootToken] = childToken; childToRootToken[childToken] = rootToken; tokenToType[rootToken] = tokenType; emit TokenMapped(rootToken, childToken, tokenType); bytes memory syncData = abi.encode(rootToken, childToken, tokenType); _stateSender.syncState( childChainManagerAddress, abi.encode(MAP_TOKEN, syncData) ); } /** * @notice Move ether from root to child chain, accepts ether transfer * Keep in mind this ether cannot be used to pay gas on child chain * Use Matic tokens deposited using plasma mechanism for that * @param user address of account that should receive WETH on child chain */ function depositEtherFor(address user) external override payable { _depositEtherFor(user); } /** * @notice Move tokens from root to child chain * @dev This mechanism supports arbitrary tokens as long as its predicate has been registered and the token is mapped * @param user address of account that should receive this deposit on child chain * @param rootToken address of token that is being deposited * @param depositData bytes data that is sent to predicate and child token contracts to handle deposit */ function depositFor( address user, address rootToken, bytes calldata depositData ) external override { require( rootToken != ETHER_ADDRESS, "RootChainManager: INVALID_ROOT_TOKEN" ); _depositFor(user, rootToken, depositData); } function _depositEtherFor(address user) private { bytes memory depositData = abi.encode(msg.value); _depositFor(user, ETHER_ADDRESS, depositData); // payable(typeToPredicate[tokenToType[ETHER_ADDRESS]]).transfer(msg.value); // transfer doesn't work as expected when receiving contract is proxified so using call (bool success, /* bytes memory data */) = typeToPredicate[tokenToType[ETHER_ADDRESS]].call{value: msg.value}(""); if (!success) { revert("RootChainManager: ETHER_TRANSFER_FAILED"); } } function _depositFor( address user, address rootToken, bytes memory depositData ) private { bytes32 tokenType = tokenToType[rootToken]; require( rootToChildToken[rootToken] != address(0x0) && tokenType != 0, "RootChainManager: TOKEN_NOT_MAPPED" ); address predicateAddress = typeToPredicate[tokenType]; require( predicateAddress != address(0), "RootChainManager: INVALID_TOKEN_TYPE" ); require( user != address(0), "RootChainManager: INVALID_USER" ); ITokenPredicate(predicateAddress).lockTokens( _msgSender(), user, rootToken, depositData ); bytes memory syncData = abi.encode(user, rootToken, depositData); _stateSender.syncState( childChainManagerAddress, abi.encode(DEPOSIT, syncData) ); } /** * @notice exit tokens by providing proof * @dev This function verifies if the transaction actually happened on child chain * the transaction log is then sent to token predicate to handle it accordingly * * @param inputData RLP encoded data of the reference tx containing following list of fields * 0 - headerNumber - Checkpoint header block number containing the reference tx * 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root * 2 - blockNumber - Block number containing the reference tx on child chain * 3 - blockTime - Reference tx block time * 4 - txRoot - Transactions root of block * 5 - receiptRoot - Receipts root of block * 6 - receipt - Receipt of the reference transaction * 7 - receiptProof - Merkle proof of the reference receipt * 8 - branchMask - 32 bits denoting the path of receipt in merkle tree * 9 - receiptLogIndex - Log Index to read from the receipt */ function exit(bytes calldata inputData) external override { ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload(); bytes memory branchMaskBytes = payload.getBranchMaskAsBytes(); // checking if exit has already been processed // unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex) bytes32 exitHash = keccak256( abi.encodePacked( payload.getBlockNumber(), // first 2 nibbles are dropped while generating nibble array // this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only) // so converting to nibble array and then hashing it MerklePatriciaProof._getNibbleArray(branchMaskBytes), payload.getReceiptLogIndex() ) ); require( processedExits[exitHash] == false, "RootChainManager: EXIT_ALREADY_PROCESSED" ); processedExits[exitHash] = true; ExitPayloadReader.Receipt memory receipt = payload.getReceipt(); ExitPayloadReader.Log memory log = receipt.getLog(); // log should be emmited only by the child token address rootToken = childToRootToken[log.getEmitter()]; require( rootToken != address(0), "RootChainManager: TOKEN_NOT_MAPPED" ); address predicateAddress = typeToPredicate[ tokenToType[rootToken] ]; // branch mask can be maximum 32 bits require( payload.getBranchMaskAsUint() & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000 == 0, "RootChainManager: INVALID_BRANCH_MASK" ); // verify receipt inclusion require( MerklePatriciaProof.verify( receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), payload.getReceiptRoot() ), "RootChainManager: INVALID_PROOF" ); // verify checkpoint inclusion _checkBlockMembershipInCheckpoint( payload.getBlockNumber(), payload.getBlockTime(), payload.getTxRoot(), payload.getReceiptRoot(), payload.getHeaderNumber(), payload.getBlockProof() ); ITokenPredicate(predicateAddress).exitTokens( rootToken, log.toRlpBytes() ); } function _checkBlockMembershipInCheckpoint( uint256 blockNumber, uint256 blockTime, bytes32 txRoot, bytes32 receiptRoot, uint256 headerNumber, bytes memory blockProof ) private view { ( bytes32 headerRoot, uint256 startBlock, , , ) = _checkpointManager.headerBlocks(headerNumber); require( keccak256( abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot) ) .checkMembership( blockNumber.sub(startBlock), headerRoot, blockProof ), "RootChainManager: INVALID_HEADER" ); } }
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"address payable","name":"relayerAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"tokenType","type":"bytes32"},{"indexed":true,"internalType":"address","name":"predicateAddress","type":"address"}],"name":"PredicateRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rootToken","type":"address"},{"indexed":true,"internalType":"address","name":"childToken","type":"address"},{"indexed":true,"internalType":"bytes32","name":"tokenType","type":"bytes32"}],"name":"TokenMapped","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC712_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETHER_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAPPER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAP_TOKEN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpointManagerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"childChainManagerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"childToRootToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rootToken","type":"address"},{"internalType":"address","name":"childToken","type":"address"}],"name":"cleanMapToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"depositEtherFor","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"rootToken","type":"address"},{"internalType":"bytes","name":"depositData","type":"bytes"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes","name":"functionSignature","type":"bytes"},{"internalType":"bytes32","name":"sigR","type":"bytes32"},{"internalType":"bytes32","name":"sigS","type":"bytes32"},{"internalType":"uint8","name":"sigV","type":"uint8"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"inputData","type":"bytes"}],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getDomainSeperator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializeEIP712","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rootToken","type":"address"},{"internalType":"address","name":"childToken","type":"address"},{"internalType":"bytes32","name":"tokenType","type":"bytes32"}],"name":"mapToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedExits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenType","type":"bytes32"},{"internalType":"address","name":"predicateAddress","type":"address"}],"name":"registerPredicate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rootToken","type":"address"},{"internalType":"address","name":"childToken","type":"address"},{"internalType":"bytes32","name":"tokenType","type":"bytes32"}],"name":"remapToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rootToChildToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newCheckpointManager","type":"address"}],"name":"setCheckpointManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newChildChainManager","type":"address"}],"name":"setChildChainManagerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newStateSender","type":"address"}],"name":"setStateSender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setupContractId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stateSenderAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToType","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"typeToPredicate","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040526000805460ff1916905534801561001a57600080fd5b5061408e8061002a6000396000f3fe6080604052600436106102295760003560e01c8063886a69ba11610123578063cf1d21c0116100ab578063e2c49de11161006f578063e2c49de1146108e8578063e3dec8fb146108fd578063e43009a614610993578063e66f9603146109c6578063ea60c7c4146109f057610240565b8063cf1d21c01461080f578063d233a3c714610824578063d547741f14610867578063d81c8e52146108a0578063dc993a23146108b557610240565b8063a217fddf116100f2578063a217fddf14610755578063b4b4f63e1461076a578063bc08452b1461077f578063c4d66de8146107b2578063ca15c873146107e557610240565b8063886a69ba146106945780639010d07c146106a95780639173b139146106d957806391d148541461071c57610240565b80633138b6f1116101b1578063568b80b511610175578063568b80b5146105c6578063607f2d42146105db578063630fcbfb146106195780636cb136b01461062e5780636e86b7701461066157610240565b80633138b6f1146104c05780633408e470146104d557806336568abe146104ea5780633805550f146105235780634faa8a26146105a057610240565b80630f7e5970116101f85780630f7e5970146103ee57806320379ee514610403578063248a9ca31461042a5780632d0335ab146104545780632f2ff15d1461048757610240565b806304967702146102455780630c3894bb146102765780630c53c51c146102b15780630c598220146103b557610240565b366102405761023e610239610a23565b610a33565b005b600080fd5b34801561025157600080fd5b5061025a610b34565b604080516001600160a01b039092168252519081900360200190f35b34801561028257600080fd5b5061023e6004803603604081101561029957600080fd5b506001600160a01b0381358116916020013516610b43565b610340600480360360a08110156102c757600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156102f257600080fd5b82018360208201111561030457600080fd5b8035906020019184600183028401116401000000008311171561032657600080fd5b91935091508035906020810135906040013560ff16610c76565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561037a578181015183820152602001610362565b50505050905090810190601f1680156103a75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103c157600080fd5b5061023e600480360360408110156103d857600080fd5b50803590602001356001600160a01b0316610eff565b3480156103fa57600080fd5b50610340610fce565b34801561040f57600080fd5b50610418610feb565b60408051918252519081900360200190f35b34801561043657600080fd5b506104186004803603602081101561044d57600080fd5b5035610ff1565b34801561046057600080fd5b506104186004803603602081101561047757600080fd5b50356001600160a01b0316611009565b34801561049357600080fd5b5061023e600480360360408110156104aa57600080fd5b50803590602001356001600160a01b0316611024565b3480156104cc57600080fd5b5061025a61108b565b3480156104e157600080fd5b5061041861109a565b3480156104f657600080fd5b5061023e6004803603604081101561050d57600080fd5b50803590602001356001600160a01b031661109e565b34801561052f57600080fd5b5061023e6004803603602081101561054657600080fd5b81019060208101813564010000000081111561056157600080fd5b82018360208201111561057357600080fd5b8035906020019184600183028401116401000000008311171561059557600080fd5b5090925090506110ff565b61023e600480360360208110156105b657600080fd5b50356001600160a01b03166114ef565b3480156105d257600080fd5b506104186114fb565b3480156105e757600080fd5b50610605600480360360208110156105fe57600080fd5b503561151e565b604080519115158252519081900360200190f35b34801561062557600080fd5b5061023e611533565b34801561063a57600080fd5b5061023e6004803603602081101561065157600080fd5b50356001600160a01b03166115d9565b34801561066d57600080fd5b5061025a6004803603602081101561068457600080fd5b50356001600160a01b03166116b6565b3480156106a057600080fd5b506104186116d1565b3480156106b557600080fd5b5061025a600480360360408110156106cc57600080fd5b50803590602001356116f2565b3480156106e557600080fd5b5061023e600480360360608110156106fc57600080fd5b506001600160a01b03813581169160208101359091169060400135611719565b34801561072857600080fd5b506106056004803603604081101561073f57600080fd5b50803590602001356001600160a01b031661184e565b34801561076157600080fd5b5061041861186c565b34801561077657600080fd5b5061023e611871565b34801561078b57600080fd5b5061023e600480360360208110156107a257600080fd5b50356001600160a01b0316611917565b3480156107be57600080fd5b5061023e600480360360208110156107d557600080fd5b50356001600160a01b03166119f4565b3480156107f157600080fd5b506104186004803603602081101561080857600080fd5b5035611ae4565b34801561081b57600080fd5b5061025a611afb565b34801561083057600080fd5b5061023e6004803603606081101561084757600080fd5b506001600160a01b03813581169160208101359091169060400135611b13565b34801561087357600080fd5b5061023e6004803603604081101561088a57600080fd5b50803590602001356001600160a01b0316611c57565b3480156108ac57600080fd5b50610418611cb0565b3480156108c157600080fd5b5061023e600480360360208110156108d857600080fd5b50356001600160a01b0316611ccf565b3480156108f457600080fd5b5061025a611dac565b34801561090957600080fd5b5061023e6004803603606081101561092057600080fd5b6001600160a01b03823581169260208101359091169181019060608101604082013564010000000081111561095457600080fd5b82018360208201111561096657600080fd5b8035906020019184600183028401116401000000008311171561098857600080fd5b509092509050611dbb565b34801561099f57600080fd5b50610418600480360360208110156109b657600080fd5b50356001600160a01b0316611e58565b3480156109d257600080fd5b5061025a600480360360208110156109e957600080fd5b5035611e6a565b3480156109fc57600080fd5b5061025a60048036036020811015610a1357600080fd5b50356001600160a01b0316611e85565b6000610a2d611ea0565b90505b90565b604080513460208083019190915282518083039091018152908201909152610a708273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee83611efd565b7fa1829a9003092132f585b6ccdd167c19fe9774dbdea4260287e8a8e8ca8185d7546000908152600260205260408082205490516001600160a01b039091169034908381818185875af1925050503d8060008114610aea576040519150601f19603f3d011682016040523d82523d6000602084013e610aef565b606091505b5050905080610b2f5760405162461bcd60e51b8152600401808060200182810382526027815260200180613f706027913960400191505060405180910390fd5b505050565b6009546001600160a01b031681565b6000610b5681610b51610a23565b61184e565b600a90610bf65760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b820191906000526020600020905b815481529060010190602001808311610bca57829003601f168201915b50509250505060405180910390fd5b506001600160a01b03808416600081815260036020908152604080832080546001600160a01b0319908116909155948716808452600483528184208054909616909555838352600590915280822082905551909291907f9e651a8866fbea043e911d816ec254b0e3c992c06fff32d605e72362d6023bd9908490a4505050565b6060610c80613c19565b604080516060810182526001600160a01b038a166000818152600c602090815290849020548352808301919091528251601f8a0182900482028101820184528981529192830191908a908a908190840183828082843760009201919091525050509152509050610cf38882878787612377565b610d2e5760405162461bcd60e51b8152600401808060200182810382526021815260200180613f976021913960400191505060405180910390fd5b6001600160a01b0388166000818152600c60209081526040918290208054600101905581518181529081018990523392917f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b918b918b919081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a360006060306001600160a01b031689898c6040516020018084848082843780830192505050826001600160a01b03166001600160a01b031660601b815260140193505050506040516020818303038152906040526040518082805190602001908083835b60208310610e345780518252601f199092019160209182019101610e15565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610e96576040519150601f19603f3d011682016040523d82523d6000602084013e610e9b565b606091505b509150915081610ef2576040805162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604482015290519081900360640190fd5b9998505050505050505050565b6000610f0d81610b51610a23565b600a90610f735760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b5060008381526002602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051909185917f8643692ae1c12ec91fa18e50b82ed93fa314f580999a236824db6de9ae0d839b9190a3505050565b604051806040016040528060018152602001603160f81b81525081565b600b5490565b6000818152600160205260409020600201545b919050565b6001600160a01b03166000908152600c602052604090205490565b60008281526001602052604090206002015461104290610b51610a23565b61107d5760405162461bcd60e51b815260040180806020018281038252602f815260200180613d96602f913960400191505060405180910390fd5b6110878282612454565b5050565b6008546001600160a01b031690565b4690565b6110a6610a23565b6001600160a01b0316816001600160a01b0316146110f55760405162461bcd60e51b815260040180806020018281038252602f81526020018061402a602f913960400191505060405180910390fd5b61108782826124c3565b611107613c43565b61114683838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061253292505050565b9050606061115382612562565b9050600061116083612585565b611169836125a8565b6111728561271b565b6040516020018084815260200183805190602001908083835b602083106111aa5780518252601f19909201916020918201910161118b565b51815160209384036101000a6000190180199092169116179052920193845250604080518085038152938201815283519382019390932060008181526006909252929020549194505060ff1615915061123690505760405162461bcd60e51b81526004018080602001828103825260288152602001806140026028913960400191505060405180910390fd5b6000818152600660205260409020805460ff19166001179055611257613c56565b61126084612731565b905061126a613c77565b6112738261281b565b905060006004600061128484612888565b6001600160a01b039081168252602082019290925260400160002054169050806112df5760405162461bcd60e51b8152600401808060200182810382526022815260200180613ecd6022913960400191505060405180910390fd5b6001600160a01b038082166000908152600560209081526040808320548352600290915290205416611310876128ab565b63ffffffff1916156113535760405162461bcd60e51b8152600401808060200182810382526025815260200180613ea86025913960400191505060405180910390fd5b61137761135f856128c1565b876113698a6128c8565b6113728b6128de565b6128f4565b6113c8576040805162461bcd60e51b815260206004820152601f60248201527f526f6f74436861696e4d616e616765723a20494e56414c49445f50524f4f4600604482015290519081900360640190fd5b6114066113d488612585565b6113dd89612b3f565b6113e68a612b55565b6113ef8b6128de565b6113f88c612b6b565b6114018d612b81565b612b97565b806001600160a01b031663f741a4178361141f86612cd4565b604080516001600160e01b031960e086901b1681526001600160a01b038416600482019081526024820192835283516044830152835190929160640190602085019080838360005b8381101561147f578181015183820152602001611467565b50505050905090810190601f1680156114ac5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114cc57600080fd5b505af11580156114e0573d6000803e3d6000fd5b50505050505050505050505050565b6114f881610a33565b50565b604080516a4d41505045525f524f4c4560a81b8152905190819003600b01902081565b60066020526000908152604090205460ff1681565b600061154181610b51610a23565b600a906115a75760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506114f86040518060400160405280601081526020016f2937b7ba21b430b4b726b0b730b3b2b960811b815250612ce3565b60006115e781610b51610a23565b600a9061164d5760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b0382166116935760405162461bcd60e51b8152600401808060200182810382526026815260200180613fb86026913960400191505060405180910390fd5b50600780546001600160a01b0319166001600160a01b0392909216919091179055565b6004602052600090815260409020546001600160a01b031681565b604080516826a0a82faa27a5a2a760b91b8152905190819003600901902081565b6000828152600160205260408120611710908363ffffffff612d9f16565b90505b92915050565b604080516a4d41505045525f524f4c4560a81b8152905190819003600b01902061174581610b51610a23565b600a906117ab5760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b03848116600090815260036020526040902054161580156117ec57506001600160a01b0383811660009081526004602052604090205416155b61183d576040805162461bcd60e51b815260206004820181905260248201527f526f6f74436861696e4d616e616765723a20414c52454144595f4d4150504544604482015290519081900360640190fd5b611848848484612dab565b50505050565b6000828152600160205260408120611710908363ffffffff61303016565b600081565b600061187f81610b51610a23565b600a906118e55760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506114f86040518060400160405280601081526020016f2937b7ba21b430b4b726b0b730b3b2b960811b815250613045565b600061192581610b51610a23565b600a9061198b5760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b0382166119d15760405162461bcd60e51b815260040180806020018281038252602c815260200180613f44602c913960400191505060405180910390fd5b50600880546001600160a01b0319166001600160a01b0392909216919091179055565b60005460ff1615611a3d576040805162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015290519081900360640190fd5b611a6e6040518060400160405280601081526020016f2937b7ba21b430b4b726b0b730b3b2b960811b8152506130e3565b611a9f6040518060400160405280601081526020016f2937b7ba21b430b4b726b0b730b3b2b960811b815250613045565b611aaa60008261107d565b604080516a4d41505045525f524f4c4560a81b8152905190819003600b019020611ad4908261107d565b506000805460ff19166001179055565b600081815260016020526040812061171390613135565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6000611b2181610b51610a23565b600a90611b875760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b0380851660009081526003602081815260408084205488861685526004835281852054861680865293909252909220549183169290911615611bfd576001600160a01b038116600090815260036020908152604080832080546001600160a01b031916905560059091528120555b6001600160a01b038281166000908152600460205260409020541615611c44576001600160a01b038216600090815260046020526040902080546001600160a01b03191690555b611c4f868686612dab565b505050505050565b600082815260016020526040902060020154611c7590610b51610a23565b6110f55760405162461bcd60e51b8152600401808060200182810382526030815260200180613eef6030913960400191505060405180910390fd5b604080516611115413d4d25560ca1b8152905190819003600701902081565b6000611cdd81610b51610a23565b600a90611d435760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b038216611d895760405162461bcd60e51b815260040180806020018281038252602d815260200180613dc5602d913960400191505060405180910390fd5b50600980546001600160a01b0319166001600160a01b0392909216919091179055565b6007546001600160a01b031690565b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611e175760405162461bcd60e51b8152600401808060200182810382526024815260200180613fde6024913960400191505060405180910390fd5b611848848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611efd92505050565b60056020526000908152604090205481565b6002602052600090815260409020546001600160a01b031681565b6003602052600090815260409020546001600160a01b031681565b600033301415611ef85760606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b03169150610a309050565b503390565b6001600160a01b0380831660009081526005602090815260408083205460039092529091205490911615801590611f3357508015155b611f6e5760405162461bcd60e51b8152600401808060200182810382526022815260200180613ecd6022913960400191505060405180910390fd5b6000818152600260205260409020546001600160a01b031680611fc25760405162461bcd60e51b8152600401808060200182810382526024815260200180613e356024913960400191505060405180910390fd5b6001600160a01b03851661201d576040805162461bcd60e51b815260206004820152601e60248201527f526f6f74436861696e4d616e616765723a20494e56414c49445f555345520000604482015290519081900360640190fd5b806001600160a01b031663e375b64e612034610a23565b8787876040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156120cb5781810151838201526020016120b3565b50505050905090810190601f1680156120f85780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561211a57600080fd5b505af115801561212e573d6000803e3d6000fd5b50505050606085858560405160200180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156121a757818101518382015260200161218f565b50505050905090810190601f1680156121d45780820380516001836020036101000a031916815260200191505b5060408051808303601f19018152828252600780546009546611115413d4d25560ca1b865284519586900390920185206020808701828152878701968752855160608901528551959d506001600160a01b039384169c506316f198319b5092909316985096508a955093608001919085019080838360005b8381101561226457818101518382015260200161224c565b50505050905090810190601f1680156122915780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040526040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561230a5781810151838201526020016122f2565b50505050905090810190601f1680156123375780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561235757600080fd5b505af115801561236b573d6000803e3d6000fd5b50505050505050505050565b60006001600160a01b0386166123be5760405162461bcd60e51b8152600401808060200182810382526025815260200180613f1f6025913960400191505060405180910390fd5b60016123d16123cc87613140565b6131cc565b83868660405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561242b573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b6000828152600160205260409020612472908263ffffffff61321816565b156110875761247f610a23565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526001602052604090206124e1908263ffffffff61322d16565b15611087576124ee610a23565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b61253a613c43565b606061254d61254884613242565b613267565b60408051602081019091529081529392505050565b6060611713826000015160088151811061257857fe5b602002602001015161334f565b6000611713826000015160028151811061259b57fe5b60200260200101516133cc565b60408051602081019091526000815281516060919015611713576000806125d0600086613419565b60f81c905060018114806125e757508060ff166003145b1561267657600185516002020367ffffffffffffffff8111801561260a57600080fd5b506040519080825280601f01601f191660200182016040528015612635576020820181803683370190505b5092506000612645600187613419565b9050808460008151811061265557fe5b60200101906001600160f81b031916908160001a90535060019250506126c7565b600285516002020367ffffffffffffffff8111801561269457600080fd5b506040519080825280601f01601f1916602001820160405280156126bf576020820181803683370190505b509250600091505b60ff82165b8351811015612712576126e78360ff16820360020187613419565b8482815181106126f357fe5b60200101906001600160f81b031916908160001a9053506001016126cc565b50505092915050565b6000611713826000015160098151811061259b57fe5b612739613c56565b61274d826000015160068151811061257857fe5b602082015261275a613c97565b6127678260200151613242565b905061277281613476565b156127875761278081613267565b8252612807565b602082015180516060906000190167ffffffffffffffff811180156127ab57600080fd5b506040519080825280601f01601f1916602001820160405280156127d6576020820181803683370190505b5090506000808360210191508260200190506127f4828285516134b0565b61280061254884613242565b8652505050505b6128108361271b565b604083015250919050565b612823613c77565b61282b613c97565b61284c836000015160038151811061283f57fe5b6020026020010151613267565b83604001518151811061285b57fe5b60200260200101519050604051806040016040528082815260200161287f83613267565b90529392505050565b6000611713826020015160008151811061289e57fe5b60200260200101516134fb565b6000611713826000015160088151811061259b57fe5b6020015190565b6060611713826000015160078151811061257857fe5b6000611713826000015160058151811061259b57fe5b60006128fe613c97565b61290784613242565b9050606061291482613267565b9050606080856000826129268b6125a8565b9050805160001415612942576000975050505050505050612b37565b60005b8651811015612b2a57815183111561296857600098505050505050505050612b37565b61298487828151811061297757fe5b6020026020010151613515565b9550858051906020012084146129a557600098505050505050505050612b37565b6129b487828151811061283f57fe5b9450845160111415612a71578151831415612a10578c805190602001206129e18660108151811061257857fe5b8051906020012014156129ff57600198505050505050505050612b37565b600098505050505050505050612b37565b6000828481518110612a1e57fe5b016020015160f81c90506010811115612a435760009950505050505050505050612b37565b612a62868260ff1681518110612a5557fe5b6020026020010151613594565b94505060019290920191612b22565b8451600214156129ff576000612a97612a908760008151811061257857fe5b84866135b1565b905082518185011415612aed578d80519060200120612abc8760018151811061257857fe5b805190602001201415612adb5760019950505050505050505050612b37565b60009950505050505050505050612b37565b80612b045760009950505050505050505050612b37565b8084019350612b1986600181518110612a5557fe5b9450612b229050565b600101612945565b5060009750505050505050505b949350505050565b6000611713826000015160038151811061259b57fe5b6000611713826000015160048151811061259b57fe5b6000611713826000015160008151811061259b57fe5b6060611713826000015160018151811061257857fe5b600854604080516320a9cea560e11b815260048101859052905160009283926001600160a01b03909116916341539d4a9160248082019260a092909190829003018186803b158015612be857600080fd5b505afa158015612bfc573d6000803e3d6000fd5b505050506040513d60a0811015612c1257600080fd5b5080516020909101519092509050612c79612c33898363ffffffff61369016565b6040805160208082018d90528183018c9052606082018b905260808083018b90528351808403909101815260a0909201909252805191012090848663ffffffff6136d216565b612cca576040805162461bcd60e51b815260206004820181905260248201527f526f6f74436861696e4d616e616765723a20494e56414c49445f484541444552604482015290519081900360640190fd5b5050505050505050565b60606117138260000151613515565b6040518060800160405280604f8152602001613e59604f913980516020918201208251838301206040805180820190915260018152603160f81b930192909252907fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc630612d4e61109a565b604080516020808201979097528082019590955260608501939093526001600160a01b03909116608084015260a0808401919091528151808403909101815260c090920190528051910120600b5550565b60006117108383613828565b6000818152600260205260409020546001600160a01b0316612dfe5760405162461bcd60e51b815260040180806020018281038252602a815260200180613d4a602a913960400191505060405180910390fd5b6001600160a01b03808416600081815260036020908152604080832080549588166001600160a01b031996871681179091558084526004835281842080549096168517909555838352600590915280822085905551849392917f9e651a8866fbea043e911d816ec254b0e3c992c06fff32d605e72362d6023bd991a4604080516001600160a01b0380861660208084019190915281861683850152606083810186905284518085038201815260808086018088526007546009546826a0a82faa27a5a2a760b91b9092528851978890036089018820888701818152898b019a8b528551968a019690965284519499918816986316f1983198939093169690958a9590949293909201919085019080838360005b83811015612f29578181015183820152602001612f11565b50505050905090810190601f168015612f565780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040526040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612fcf578181015183820152602001612fb7565b50505050905090810190601f168015612ffc5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561301c57600080fd5b505af1158015612cca573d6000803e3d6000fd5b6000611710836001600160a01b03841661388c565b806040516020018082805190602001908083835b602083106130785780518252601f199092019160209182019101613059565b51815160209384036101000a60001901801990921691161790527f3a20494e53554646494349454e545f5045524d495353494f4e530000000000009190930190815260408051808303600519018152601a909201905280516110879550600a94509201919050613cb1565b60005460ff161561312c576040805162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015290519081900360640190fd5b611ad481612ce3565b6000611713826138a4565b6000604051806080016040528060438152602001613df260439139805190602001208260000151836020015184604001518051906020012060405160200180858152602001848152602001836001600160a01b03166001600160a01b03168152602001828152602001945050505050604051602081830303815290604052805190602001209050919050565b60006131d6610feb565b82604051602001808061190160f01b81525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050919050565b6000611710836001600160a01b0384166138a8565b6000611710836001600160a01b0384166138f2565b61324a613c97565b506040805180820190915281518152602082810190820152919050565b606061327282613476565b61327b57600080fd5b6000613286836139b8565b905060608167ffffffffffffffff811180156132a157600080fd5b506040519080825280602002602001820160405280156132db57816020015b6132c8613c97565b8152602001906001900390816132c05790505b50905060006132ed8560200151613a14565b60208601510190506000805b848110156133445761330a83613a77565b915060405180604001604052808381526020018481525084828151811061332d57fe5b6020908102919091010152918101916001016132f9565b509195945050505050565b805160609061335d57600080fd5b60008061336984613b0b565b9150915060608167ffffffffffffffff8111801561338657600080fd5b506040519080825280601f01601f1916602001820160405280156133b1576020820181803683370190505b509050602081016133c3848285613b31565b50949350505050565b8051600090158015906133e157508151602110155b6133ea57600080fd5b6000806133f684613b0b565b815191935091506020821015612b375760208290036101000a9004949350505050565b6000600283061561344a57601082600285048151811061343557fe5b016020015160f81c8161344457fe5b0661346c565b601082600285048151811061345b57fe5b016020015160f81c8161346a57fe5b045b60f81b9392505050565b805160009061348757506000611004565b6020820151805160001a9060c08210156134a657600092505050611004565b5060019392505050565b806134ba57610b2f565b5b602081106134da578251825260209283019290910190601f19016134bb565b915181516020939093036101000a6000190180199091169216919091179052565b805160009060151461350c57600080fd5b611713826133cc565b606080826000015167ffffffffffffffff8111801561353357600080fd5b506040519080825280601f01601f19166020018201604052801561355e576020820181803683370190505b509050805160001415613572579050611004565b600081602001905061358d8460200151828660000151613b31565b5092915050565b80516000906021146135a557600080fd5b50602001516001015190565b60008060606135bf866125a8565b90506060815167ffffffffffffffff811180156135db57600080fd5b506040519080825280601f01601f191660200182016040528015613606576020820181803683370190505b509050845b8251860181101561366057600087828151811061362457fe5b602001015160f81c60f81b905080838884038151811061364057fe5b60200101906001600160f81b031916908160001a9053505060010161360b565b508080519060200120828051906020012014156136805781519250613685565b600092505b509095945050505050565b600061171083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b82565b600060208251816136df57fe5b0615613729576040805162461bcd60e51b8152602060048201526014602482015273092dcecc2d8d2c840e0e4dedecc40d8cadccee8d60631b604482015290519081900360640190fd5b6000602083518161373657fe5b0490508060020a8510613788576040805162461bcd60e51b81526020600482015260156024820152744c65616620696e64657820697320746f6f2062696760581b604482015290519081900360640190fd5b60008660205b8551811161381a57858101519250600288066137da578183604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120915061380c565b828260405160200180838152602001828152602001925050506040516020818303038152906040528051906020012091505b60028804975060200161378e565b509094149695505050505050565b8154600090821061386a5760405162461bcd60e51b8152600401808060200182810382526022815260200180613d746022913960400191505060405180910390fd5b82600001828154811061387957fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b60006138b4838361388c565b6138ea57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611713565b506000611713565b600081815260018301602052604081205480156139ae578354600019808301919081019060009087908390811061392557fe5b906000526020600020015490508087600001848154811061394257fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061397257fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611713565b6000915050611713565b80516000906139c957506000611004565b600080905060006139dd8460200151613a14565b602085015185519181019250015b80821015613a0b576139fc82613a77565b600190930192909101906139eb565b50909392505050565b8051600090811a6080811015613a2e576000915050611004565b60b8811080613a49575060c08110801590613a49575060f881105b15613a58576001915050611004565b60c0811015613a6c5760b519019050611004565b60f519019050611004565b80516000908190811a6080811015613a92576001915061358d565b60b8811015613aa757607e198101915061358d565b60c0811015613ad45760b78103600185019450806020036101000a8551046001820181019350505061358d565b60f8811015613ae95760be198101915061358d565b60019390930151602084900360f7016101000a900490920160f5190192915050565b6000806000613b1d8460200151613a14565b602085015194519481019594039392505050565b80613b3b57610b2f565b5b60208110613b5b578251825260209283019290910190601f1901613b3c565b8015610b2f57915181516020939093036101000a6000190180199091169216919091179052565b60008184841115613c115760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613bd6578181015183820152602001613bbe565b50505050905090810190601f168015613c035780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180606001604052806000815260200160006001600160a01b03168152602001606081525090565b6040518060200160405280606081525090565b60405180606001604052806060815260200160608152602001600081525090565b6040518060400160405280613c8a613c97565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613cf257805160ff1916838001178555613d1f565b82800160010185558215613d1f579182015b82811115613d1f578251825591602001919060010190613d04565b50613d2b929150613d2f565b5090565b610a3091905b80821115613d2b5760008155600101613d3556fe526f6f74436861696e4d616e616765723a20544f4b454e5f545950455f4e4f545f535550504f52544544456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74526f6f74436861696e4d616e616765723a20494e56414c49445f4348494c445f434841494e5f414444524553534d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529526f6f74436861696e4d616e616765723a20494e56414c49445f544f4b454e5f54595045454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c7429526f6f74436861696e4d616e616765723a20494e56414c49445f4252414e43485f4d41534b526f6f74436861696e4d616e616765723a20544f4b454e5f4e4f545f4d4150504544416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5349474e4552526f6f74436861696e4d616e616765723a204241445f4e45575f434845434b504f494e545f4d414e41474552526f6f74436861696e4d616e616765723a2045544845525f5452414e534645525f4641494c45445369676e657220616e64207369676e617475726520646f206e6f74206d61746368526f6f74436861696e4d616e616765723a204241445f4e45575f53544154455f53454e444552526f6f74436861696e4d616e616765723a20494e56414c49445f524f4f545f544f4b454e526f6f74436861696e4d616e616765723a20455849545f414c52454144595f50524f434553534544416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212205dff4876821f39240dc4251f6b691bc1a025719014956c8de7463f264b9c977664736f6c63430006060033
Deployed Bytecode
0x6080604052600436106102295760003560e01c8063886a69ba11610123578063cf1d21c0116100ab578063e2c49de11161006f578063e2c49de1146108e8578063e3dec8fb146108fd578063e43009a614610993578063e66f9603146109c6578063ea60c7c4146109f057610240565b8063cf1d21c01461080f578063d233a3c714610824578063d547741f14610867578063d81c8e52146108a0578063dc993a23146108b557610240565b8063a217fddf116100f2578063a217fddf14610755578063b4b4f63e1461076a578063bc08452b1461077f578063c4d66de8146107b2578063ca15c873146107e557610240565b8063886a69ba146106945780639010d07c146106a95780639173b139146106d957806391d148541461071c57610240565b80633138b6f1116101b1578063568b80b511610175578063568b80b5146105c6578063607f2d42146105db578063630fcbfb146106195780636cb136b01461062e5780636e86b7701461066157610240565b80633138b6f1146104c05780633408e470146104d557806336568abe146104ea5780633805550f146105235780634faa8a26146105a057610240565b80630f7e5970116101f85780630f7e5970146103ee57806320379ee514610403578063248a9ca31461042a5780632d0335ab146104545780632f2ff15d1461048757610240565b806304967702146102455780630c3894bb146102765780630c53c51c146102b15780630c598220146103b557610240565b366102405761023e610239610a23565b610a33565b005b600080fd5b34801561025157600080fd5b5061025a610b34565b604080516001600160a01b039092168252519081900360200190f35b34801561028257600080fd5b5061023e6004803603604081101561029957600080fd5b506001600160a01b0381358116916020013516610b43565b610340600480360360a08110156102c757600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156102f257600080fd5b82018360208201111561030457600080fd5b8035906020019184600183028401116401000000008311171561032657600080fd5b91935091508035906020810135906040013560ff16610c76565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561037a578181015183820152602001610362565b50505050905090810190601f1680156103a75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103c157600080fd5b5061023e600480360360408110156103d857600080fd5b50803590602001356001600160a01b0316610eff565b3480156103fa57600080fd5b50610340610fce565b34801561040f57600080fd5b50610418610feb565b60408051918252519081900360200190f35b34801561043657600080fd5b506104186004803603602081101561044d57600080fd5b5035610ff1565b34801561046057600080fd5b506104186004803603602081101561047757600080fd5b50356001600160a01b0316611009565b34801561049357600080fd5b5061023e600480360360408110156104aa57600080fd5b50803590602001356001600160a01b0316611024565b3480156104cc57600080fd5b5061025a61108b565b3480156104e157600080fd5b5061041861109a565b3480156104f657600080fd5b5061023e6004803603604081101561050d57600080fd5b50803590602001356001600160a01b031661109e565b34801561052f57600080fd5b5061023e6004803603602081101561054657600080fd5b81019060208101813564010000000081111561056157600080fd5b82018360208201111561057357600080fd5b8035906020019184600183028401116401000000008311171561059557600080fd5b5090925090506110ff565b61023e600480360360208110156105b657600080fd5b50356001600160a01b03166114ef565b3480156105d257600080fd5b506104186114fb565b3480156105e757600080fd5b50610605600480360360208110156105fe57600080fd5b503561151e565b604080519115158252519081900360200190f35b34801561062557600080fd5b5061023e611533565b34801561063a57600080fd5b5061023e6004803603602081101561065157600080fd5b50356001600160a01b03166115d9565b34801561066d57600080fd5b5061025a6004803603602081101561068457600080fd5b50356001600160a01b03166116b6565b3480156106a057600080fd5b506104186116d1565b3480156106b557600080fd5b5061025a600480360360408110156106cc57600080fd5b50803590602001356116f2565b3480156106e557600080fd5b5061023e600480360360608110156106fc57600080fd5b506001600160a01b03813581169160208101359091169060400135611719565b34801561072857600080fd5b506106056004803603604081101561073f57600080fd5b50803590602001356001600160a01b031661184e565b34801561076157600080fd5b5061041861186c565b34801561077657600080fd5b5061023e611871565b34801561078b57600080fd5b5061023e600480360360208110156107a257600080fd5b50356001600160a01b0316611917565b3480156107be57600080fd5b5061023e600480360360208110156107d557600080fd5b50356001600160a01b03166119f4565b3480156107f157600080fd5b506104186004803603602081101561080857600080fd5b5035611ae4565b34801561081b57600080fd5b5061025a611afb565b34801561083057600080fd5b5061023e6004803603606081101561084757600080fd5b506001600160a01b03813581169160208101359091169060400135611b13565b34801561087357600080fd5b5061023e6004803603604081101561088a57600080fd5b50803590602001356001600160a01b0316611c57565b3480156108ac57600080fd5b50610418611cb0565b3480156108c157600080fd5b5061023e600480360360208110156108d857600080fd5b50356001600160a01b0316611ccf565b3480156108f457600080fd5b5061025a611dac565b34801561090957600080fd5b5061023e6004803603606081101561092057600080fd5b6001600160a01b03823581169260208101359091169181019060608101604082013564010000000081111561095457600080fd5b82018360208201111561096657600080fd5b8035906020019184600183028401116401000000008311171561098857600080fd5b509092509050611dbb565b34801561099f57600080fd5b50610418600480360360208110156109b657600080fd5b50356001600160a01b0316611e58565b3480156109d257600080fd5b5061025a600480360360208110156109e957600080fd5b5035611e6a565b3480156109fc57600080fd5b5061025a60048036036020811015610a1357600080fd5b50356001600160a01b0316611e85565b6000610a2d611ea0565b90505b90565b604080513460208083019190915282518083039091018152908201909152610a708273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee83611efd565b7fa1829a9003092132f585b6ccdd167c19fe9774dbdea4260287e8a8e8ca8185d7546000908152600260205260408082205490516001600160a01b039091169034908381818185875af1925050503d8060008114610aea576040519150601f19603f3d011682016040523d82523d6000602084013e610aef565b606091505b5050905080610b2f5760405162461bcd60e51b8152600401808060200182810382526027815260200180613f706027913960400191505060405180910390fd5b505050565b6009546001600160a01b031681565b6000610b5681610b51610a23565b61184e565b600a90610bf65760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b820191906000526020600020905b815481529060010190602001808311610bca57829003601f168201915b50509250505060405180910390fd5b506001600160a01b03808416600081815260036020908152604080832080546001600160a01b0319908116909155948716808452600483528184208054909616909555838352600590915280822082905551909291907f9e651a8866fbea043e911d816ec254b0e3c992c06fff32d605e72362d6023bd9908490a4505050565b6060610c80613c19565b604080516060810182526001600160a01b038a166000818152600c602090815290849020548352808301919091528251601f8a0182900482028101820184528981529192830191908a908a908190840183828082843760009201919091525050509152509050610cf38882878787612377565b610d2e5760405162461bcd60e51b8152600401808060200182810382526021815260200180613f976021913960400191505060405180910390fd5b6001600160a01b0388166000818152600c60209081526040918290208054600101905581518181529081018990523392917f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b918b918b919081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a360006060306001600160a01b031689898c6040516020018084848082843780830192505050826001600160a01b03166001600160a01b031660601b815260140193505050506040516020818303038152906040526040518082805190602001908083835b60208310610e345780518252601f199092019160209182019101610e15565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610e96576040519150601f19603f3d011682016040523d82523d6000602084013e610e9b565b606091505b509150915081610ef2576040805162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604482015290519081900360640190fd5b9998505050505050505050565b6000610f0d81610b51610a23565b600a90610f735760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b5060008381526002602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051909185917f8643692ae1c12ec91fa18e50b82ed93fa314f580999a236824db6de9ae0d839b9190a3505050565b604051806040016040528060018152602001603160f81b81525081565b600b5490565b6000818152600160205260409020600201545b919050565b6001600160a01b03166000908152600c602052604090205490565b60008281526001602052604090206002015461104290610b51610a23565b61107d5760405162461bcd60e51b815260040180806020018281038252602f815260200180613d96602f913960400191505060405180910390fd5b6110878282612454565b5050565b6008546001600160a01b031690565b4690565b6110a6610a23565b6001600160a01b0316816001600160a01b0316146110f55760405162461bcd60e51b815260040180806020018281038252602f81526020018061402a602f913960400191505060405180910390fd5b61108782826124c3565b611107613c43565b61114683838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061253292505050565b9050606061115382612562565b9050600061116083612585565b611169836125a8565b6111728561271b565b6040516020018084815260200183805190602001908083835b602083106111aa5780518252601f19909201916020918201910161118b565b51815160209384036101000a6000190180199092169116179052920193845250604080518085038152938201815283519382019390932060008181526006909252929020549194505060ff1615915061123690505760405162461bcd60e51b81526004018080602001828103825260288152602001806140026028913960400191505060405180910390fd5b6000818152600660205260409020805460ff19166001179055611257613c56565b61126084612731565b905061126a613c77565b6112738261281b565b905060006004600061128484612888565b6001600160a01b039081168252602082019290925260400160002054169050806112df5760405162461bcd60e51b8152600401808060200182810382526022815260200180613ecd6022913960400191505060405180910390fd5b6001600160a01b038082166000908152600560209081526040808320548352600290915290205416611310876128ab565b63ffffffff1916156113535760405162461bcd60e51b8152600401808060200182810382526025815260200180613ea86025913960400191505060405180910390fd5b61137761135f856128c1565b876113698a6128c8565b6113728b6128de565b6128f4565b6113c8576040805162461bcd60e51b815260206004820152601f60248201527f526f6f74436861696e4d616e616765723a20494e56414c49445f50524f4f4600604482015290519081900360640190fd5b6114066113d488612585565b6113dd89612b3f565b6113e68a612b55565b6113ef8b6128de565b6113f88c612b6b565b6114018d612b81565b612b97565b806001600160a01b031663f741a4178361141f86612cd4565b604080516001600160e01b031960e086901b1681526001600160a01b038416600482019081526024820192835283516044830152835190929160640190602085019080838360005b8381101561147f578181015183820152602001611467565b50505050905090810190601f1680156114ac5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114cc57600080fd5b505af11580156114e0573d6000803e3d6000fd5b50505050505050505050505050565b6114f881610a33565b50565b604080516a4d41505045525f524f4c4560a81b8152905190819003600b01902081565b60066020526000908152604090205460ff1681565b600061154181610b51610a23565b600a906115a75760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506114f86040518060400160405280601081526020016f2937b7ba21b430b4b726b0b730b3b2b960811b815250612ce3565b60006115e781610b51610a23565b600a9061164d5760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b0382166116935760405162461bcd60e51b8152600401808060200182810382526026815260200180613fb86026913960400191505060405180910390fd5b50600780546001600160a01b0319166001600160a01b0392909216919091179055565b6004602052600090815260409020546001600160a01b031681565b604080516826a0a82faa27a5a2a760b91b8152905190819003600901902081565b6000828152600160205260408120611710908363ffffffff612d9f16565b90505b92915050565b604080516a4d41505045525f524f4c4560a81b8152905190819003600b01902061174581610b51610a23565b600a906117ab5760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b03848116600090815260036020526040902054161580156117ec57506001600160a01b0383811660009081526004602052604090205416155b61183d576040805162461bcd60e51b815260206004820181905260248201527f526f6f74436861696e4d616e616765723a20414c52454144595f4d4150504544604482015290519081900360640190fd5b611848848484612dab565b50505050565b6000828152600160205260408120611710908363ffffffff61303016565b600081565b600061187f81610b51610a23565b600a906118e55760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506114f86040518060400160405280601081526020016f2937b7ba21b430b4b726b0b730b3b2b960811b815250613045565b600061192581610b51610a23565b600a9061198b5760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b0382166119d15760405162461bcd60e51b815260040180806020018281038252602c815260200180613f44602c913960400191505060405180910390fd5b50600880546001600160a01b0319166001600160a01b0392909216919091179055565b60005460ff1615611a3d576040805162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015290519081900360640190fd5b611a6e6040518060400160405280601081526020016f2937b7ba21b430b4b726b0b730b3b2b960811b8152506130e3565b611a9f6040518060400160405280601081526020016f2937b7ba21b430b4b726b0b730b3b2b960811b815250613045565b611aaa60008261107d565b604080516a4d41505045525f524f4c4560a81b8152905190819003600b019020611ad4908261107d565b506000805460ff19166001179055565b600081815260016020526040812061171390613135565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6000611b2181610b51610a23565b600a90611b875760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b0380851660009081526003602081815260408084205488861685526004835281852054861680865293909252909220549183169290911615611bfd576001600160a01b038116600090815260036020908152604080832080546001600160a01b031916905560059091528120555b6001600160a01b038281166000908152600460205260409020541615611c44576001600160a01b038216600090815260046020526040902080546001600160a01b03191690555b611c4f868686612dab565b505050505050565b600082815260016020526040902060020154611c7590610b51610a23565b6110f55760405162461bcd60e51b8152600401808060200182810382526030815260200180613eef6030913960400191505060405180910390fd5b604080516611115413d4d25560ca1b8152905190819003600701902081565b6000611cdd81610b51610a23565b600a90611d435760405162461bcd60e51b8152602060048201908152825460026000196101006001841615020190911604602483018190529091829160449091019084908015610be75780601f10610bbc57610100808354040283529160200191610be7565b506001600160a01b038216611d895760405162461bcd60e51b815260040180806020018281038252602d815260200180613dc5602d913960400191505060405180910390fd5b50600980546001600160a01b0319166001600160a01b0392909216919091179055565b6007546001600160a01b031690565b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611e175760405162461bcd60e51b8152600401808060200182810382526024815260200180613fde6024913960400191505060405180910390fd5b611848848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611efd92505050565b60056020526000908152604090205481565b6002602052600090815260409020546001600160a01b031681565b6003602052600090815260409020546001600160a01b031681565b600033301415611ef85760606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b03169150610a309050565b503390565b6001600160a01b0380831660009081526005602090815260408083205460039092529091205490911615801590611f3357508015155b611f6e5760405162461bcd60e51b8152600401808060200182810382526022815260200180613ecd6022913960400191505060405180910390fd5b6000818152600260205260409020546001600160a01b031680611fc25760405162461bcd60e51b8152600401808060200182810382526024815260200180613e356024913960400191505060405180910390fd5b6001600160a01b03851661201d576040805162461bcd60e51b815260206004820152601e60248201527f526f6f74436861696e4d616e616765723a20494e56414c49445f555345520000604482015290519081900360640190fd5b806001600160a01b031663e375b64e612034610a23565b8787876040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156120cb5781810151838201526020016120b3565b50505050905090810190601f1680156120f85780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561211a57600080fd5b505af115801561212e573d6000803e3d6000fd5b50505050606085858560405160200180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b838110156121a757818101518382015260200161218f565b50505050905090810190601f1680156121d45780820380516001836020036101000a031916815260200191505b5060408051808303601f19018152828252600780546009546611115413d4d25560ca1b865284519586900390920185206020808701828152878701968752855160608901528551959d506001600160a01b039384169c506316f198319b5092909316985096508a955093608001919085019080838360005b8381101561226457818101518382015260200161224c565b50505050905090810190601f1680156122915780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040526040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561230a5781810151838201526020016122f2565b50505050905090810190601f1680156123375780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561235757600080fd5b505af115801561236b573d6000803e3d6000fd5b50505050505050505050565b60006001600160a01b0386166123be5760405162461bcd60e51b8152600401808060200182810382526025815260200180613f1f6025913960400191505060405180910390fd5b60016123d16123cc87613140565b6131cc565b83868660405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561242b573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b6000828152600160205260409020612472908263ffffffff61321816565b156110875761247f610a23565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526001602052604090206124e1908263ffffffff61322d16565b15611087576124ee610a23565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b61253a613c43565b606061254d61254884613242565b613267565b60408051602081019091529081529392505050565b6060611713826000015160088151811061257857fe5b602002602001015161334f565b6000611713826000015160028151811061259b57fe5b60200260200101516133cc565b60408051602081019091526000815281516060919015611713576000806125d0600086613419565b60f81c905060018114806125e757508060ff166003145b1561267657600185516002020367ffffffffffffffff8111801561260a57600080fd5b506040519080825280601f01601f191660200182016040528015612635576020820181803683370190505b5092506000612645600187613419565b9050808460008151811061265557fe5b60200101906001600160f81b031916908160001a90535060019250506126c7565b600285516002020367ffffffffffffffff8111801561269457600080fd5b506040519080825280601f01601f1916602001820160405280156126bf576020820181803683370190505b509250600091505b60ff82165b8351811015612712576126e78360ff16820360020187613419565b8482815181106126f357fe5b60200101906001600160f81b031916908160001a9053506001016126cc565b50505092915050565b6000611713826000015160098151811061259b57fe5b612739613c56565b61274d826000015160068151811061257857fe5b602082015261275a613c97565b6127678260200151613242565b905061277281613476565b156127875761278081613267565b8252612807565b602082015180516060906000190167ffffffffffffffff811180156127ab57600080fd5b506040519080825280601f01601f1916602001820160405280156127d6576020820181803683370190505b5090506000808360210191508260200190506127f4828285516134b0565b61280061254884613242565b8652505050505b6128108361271b565b604083015250919050565b612823613c77565b61282b613c97565b61284c836000015160038151811061283f57fe5b6020026020010151613267565b83604001518151811061285b57fe5b60200260200101519050604051806040016040528082815260200161287f83613267565b90529392505050565b6000611713826020015160008151811061289e57fe5b60200260200101516134fb565b6000611713826000015160088151811061259b57fe5b6020015190565b6060611713826000015160078151811061257857fe5b6000611713826000015160058151811061259b57fe5b60006128fe613c97565b61290784613242565b9050606061291482613267565b9050606080856000826129268b6125a8565b9050805160001415612942576000975050505050505050612b37565b60005b8651811015612b2a57815183111561296857600098505050505050505050612b37565b61298487828151811061297757fe5b6020026020010151613515565b9550858051906020012084146129a557600098505050505050505050612b37565b6129b487828151811061283f57fe5b9450845160111415612a71578151831415612a10578c805190602001206129e18660108151811061257857fe5b8051906020012014156129ff57600198505050505050505050612b37565b600098505050505050505050612b37565b6000828481518110612a1e57fe5b016020015160f81c90506010811115612a435760009950505050505050505050612b37565b612a62868260ff1681518110612a5557fe5b6020026020010151613594565b94505060019290920191612b22565b8451600214156129ff576000612a97612a908760008151811061257857fe5b84866135b1565b905082518185011415612aed578d80519060200120612abc8760018151811061257857fe5b805190602001201415612adb5760019950505050505050505050612b37565b60009950505050505050505050612b37565b80612b045760009950505050505050505050612b37565b8084019350612b1986600181518110612a5557fe5b9450612b229050565b600101612945565b5060009750505050505050505b949350505050565b6000611713826000015160038151811061259b57fe5b6000611713826000015160048151811061259b57fe5b6000611713826000015160008151811061259b57fe5b6060611713826000015160018151811061257857fe5b600854604080516320a9cea560e11b815260048101859052905160009283926001600160a01b03909116916341539d4a9160248082019260a092909190829003018186803b158015612be857600080fd5b505afa158015612bfc573d6000803e3d6000fd5b505050506040513d60a0811015612c1257600080fd5b5080516020909101519092509050612c79612c33898363ffffffff61369016565b6040805160208082018d90528183018c9052606082018b905260808083018b90528351808403909101815260a0909201909252805191012090848663ffffffff6136d216565b612cca576040805162461bcd60e51b815260206004820181905260248201527f526f6f74436861696e4d616e616765723a20494e56414c49445f484541444552604482015290519081900360640190fd5b5050505050505050565b60606117138260000151613515565b6040518060800160405280604f8152602001613e59604f913980516020918201208251838301206040805180820190915260018152603160f81b930192909252907fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc630612d4e61109a565b604080516020808201979097528082019590955260608501939093526001600160a01b03909116608084015260a0808401919091528151808403909101815260c090920190528051910120600b5550565b60006117108383613828565b6000818152600260205260409020546001600160a01b0316612dfe5760405162461bcd60e51b815260040180806020018281038252602a815260200180613d4a602a913960400191505060405180910390fd5b6001600160a01b03808416600081815260036020908152604080832080549588166001600160a01b031996871681179091558084526004835281842080549096168517909555838352600590915280822085905551849392917f9e651a8866fbea043e911d816ec254b0e3c992c06fff32d605e72362d6023bd991a4604080516001600160a01b0380861660208084019190915281861683850152606083810186905284518085038201815260808086018088526007546009546826a0a82faa27a5a2a760b91b9092528851978890036089018820888701818152898b019a8b528551968a019690965284519499918816986316f1983198939093169690958a9590949293909201919085019080838360005b83811015612f29578181015183820152602001612f11565b50505050905090810190601f168015612f565780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040526040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612fcf578181015183820152602001612fb7565b50505050905090810190601f168015612ffc5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561301c57600080fd5b505af1158015612cca573d6000803e3d6000fd5b6000611710836001600160a01b03841661388c565b806040516020018082805190602001908083835b602083106130785780518252601f199092019160209182019101613059565b51815160209384036101000a60001901801990921691161790527f3a20494e53554646494349454e545f5045524d495353494f4e530000000000009190930190815260408051808303600519018152601a909201905280516110879550600a94509201919050613cb1565b60005460ff161561312c576040805162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015290519081900360640190fd5b611ad481612ce3565b6000611713826138a4565b6000604051806080016040528060438152602001613df260439139805190602001208260000151836020015184604001518051906020012060405160200180858152602001848152602001836001600160a01b03166001600160a01b03168152602001828152602001945050505050604051602081830303815290604052805190602001209050919050565b60006131d6610feb565b82604051602001808061190160f01b81525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050919050565b6000611710836001600160a01b0384166138a8565b6000611710836001600160a01b0384166138f2565b61324a613c97565b506040805180820190915281518152602082810190820152919050565b606061327282613476565b61327b57600080fd5b6000613286836139b8565b905060608167ffffffffffffffff811180156132a157600080fd5b506040519080825280602002602001820160405280156132db57816020015b6132c8613c97565b8152602001906001900390816132c05790505b50905060006132ed8560200151613a14565b60208601510190506000805b848110156133445761330a83613a77565b915060405180604001604052808381526020018481525084828151811061332d57fe5b6020908102919091010152918101916001016132f9565b509195945050505050565b805160609061335d57600080fd5b60008061336984613b0b565b9150915060608167ffffffffffffffff8111801561338657600080fd5b506040519080825280601f01601f1916602001820160405280156133b1576020820181803683370190505b509050602081016133c3848285613b31565b50949350505050565b8051600090158015906133e157508151602110155b6133ea57600080fd5b6000806133f684613b0b565b815191935091506020821015612b375760208290036101000a9004949350505050565b6000600283061561344a57601082600285048151811061343557fe5b016020015160f81c8161344457fe5b0661346c565b601082600285048151811061345b57fe5b016020015160f81c8161346a57fe5b045b60f81b9392505050565b805160009061348757506000611004565b6020820151805160001a9060c08210156134a657600092505050611004565b5060019392505050565b806134ba57610b2f565b5b602081106134da578251825260209283019290910190601f19016134bb565b915181516020939093036101000a6000190180199091169216919091179052565b805160009060151461350c57600080fd5b611713826133cc565b606080826000015167ffffffffffffffff8111801561353357600080fd5b506040519080825280601f01601f19166020018201604052801561355e576020820181803683370190505b509050805160001415613572579050611004565b600081602001905061358d8460200151828660000151613b31565b5092915050565b80516000906021146135a557600080fd5b50602001516001015190565b60008060606135bf866125a8565b90506060815167ffffffffffffffff811180156135db57600080fd5b506040519080825280601f01601f191660200182016040528015613606576020820181803683370190505b509050845b8251860181101561366057600087828151811061362457fe5b602001015160f81c60f81b905080838884038151811061364057fe5b60200101906001600160f81b031916908160001a9053505060010161360b565b508080519060200120828051906020012014156136805781519250613685565b600092505b509095945050505050565b600061171083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b82565b600060208251816136df57fe5b0615613729576040805162461bcd60e51b8152602060048201526014602482015273092dcecc2d8d2c840e0e4dedecc40d8cadccee8d60631b604482015290519081900360640190fd5b6000602083518161373657fe5b0490508060020a8510613788576040805162461bcd60e51b81526020600482015260156024820152744c65616620696e64657820697320746f6f2062696760581b604482015290519081900360640190fd5b60008660205b8551811161381a57858101519250600288066137da578183604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120915061380c565b828260405160200180838152602001828152602001925050506040516020818303038152906040528051906020012091505b60028804975060200161378e565b509094149695505050505050565b8154600090821061386a5760405162461bcd60e51b8152600401808060200182810382526022815260200180613d746022913960400191505060405180910390fd5b82600001828154811061387957fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b60006138b4838361388c565b6138ea57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611713565b506000611713565b600081815260018301602052604081205480156139ae578354600019808301919081019060009087908390811061392557fe5b906000526020600020015490508087600001848154811061394257fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061397257fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611713565b6000915050611713565b80516000906139c957506000611004565b600080905060006139dd8460200151613a14565b602085015185519181019250015b80821015613a0b576139fc82613a77565b600190930192909101906139eb565b50909392505050565b8051600090811a6080811015613a2e576000915050611004565b60b8811080613a49575060c08110801590613a49575060f881105b15613a58576001915050611004565b60c0811015613a6c5760b519019050611004565b60f519019050611004565b80516000908190811a6080811015613a92576001915061358d565b60b8811015613aa757607e198101915061358d565b60c0811015613ad45760b78103600185019450806020036101000a8551046001820181019350505061358d565b60f8811015613ae95760be198101915061358d565b60019390930151602084900360f7016101000a900490920160f5190192915050565b6000806000613b1d8460200151613a14565b602085015194519481019594039392505050565b80613b3b57610b2f565b5b60208110613b5b578251825260209283019290910190601f1901613b3c565b8015610b2f57915181516020939093036101000a6000190180199091169216919091179052565b60008184841115613c115760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613bd6578181015183820152602001613bbe565b50505050905090810190601f168015613c035780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180606001604052806000815260200160006001600160a01b03168152602001606081525090565b6040518060200160405280606081525090565b60405180606001604052806060815260200160608152602001600081525090565b6040518060400160405280613c8a613c97565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613cf257805160ff1916838001178555613d1f565b82800160010185558215613d1f579182015b82811115613d1f578251825591602001919060010190613d04565b50613d2b929150613d2f565b5090565b610a3091905b80821115613d2b5760008155600101613d3556fe526f6f74436861696e4d616e616765723a20544f4b454e5f545950455f4e4f545f535550504f52544544456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74526f6f74436861696e4d616e616765723a20494e56414c49445f4348494c445f434841494e5f414444524553534d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529526f6f74436861696e4d616e616765723a20494e56414c49445f544f4b454e5f54595045454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c7429526f6f74436861696e4d616e616765723a20494e56414c49445f4252414e43485f4d41534b526f6f74436861696e4d616e616765723a20544f4b454e5f4e4f545f4d4150504544416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5349474e4552526f6f74436861696e4d616e616765723a204241445f4e45575f434845434b504f494e545f4d414e41474552526f6f74436861696e4d616e616765723a2045544845525f5452414e534645525f4641494c45445369676e657220616e64207369676e617475726520646f206e6f74206d61746368526f6f74436861696e4d616e616765723a204241445f4e45575f53544154455f53454e444552526f6f74436861696e4d616e616765723a20494e56414c49445f524f4f545f544f4b454e526f6f74436861696e4d616e616765723a20455849545f414c52454144595f50524f434553534544416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212205dff4876821f39240dc4251f6b691bc1a025719014956c8de7463f264b9c977664736f6c63430006060033
Deployed Bytecode Sourcemap
61758:15590:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63068:30;63085:12;:10;:12::i;:::-;63068:16;:30::i;:::-;61758:15590;;12:1:-1;9;2:12;7706:39:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;7706:39:0;;;:::i;:::-;;;;-1:-1:-1;;;;;7706:39:0;;;;;;;;;;;;;;67989:363;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67989:363:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;;67989:363:0;;;;;;;;;;:::i;35284:1119::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;;;;;35284:1119:0;;;;;;;;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;35284:1119:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;35284:1119: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;35284:1119:0;;-1:-1:-1;35284:1119:0;-1:-1:-1;35284:1119:0;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;35284:1119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66694:275;;5:9:-1;2:2;;;27:1;24;17:12;2:2;66694:275:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;66694:275:0;;;;;;-1:-1:-1;;;;;66694:275:0;;:::i;32447:43::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;32447:43:0;;;:::i;33457:101::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;33457:101:0;;;:::i;:::-;;;;;;;;;;;;;;;;57174:114;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57174:114:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;57174:114:0;;:::i;36411:109::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;36411:109:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;36411:109:0;-1:-1:-1;;;;;36411:109:0;;:::i;57550:227::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;57550:227:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;57550:227:0;;;;;;-1:-1:-1;;;;;57550:227:0;;:::i;65640:121::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;65640:121:0;;;:::i;33566:161::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;33566:161:0;;;:::i;58759:209::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58759:209:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;58759:209:0;;;;;;-1:-1:-1;;;;;58759:209:0;;:::i;73956:2611::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;73956:2611:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;73956:2611:0;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;73956:2611:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;73956:2611: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;-1:-1;73956:2611:0;;-1:-1:-1;73956:2611:0;-1:-1:-1;73956:2611:0;:::i;70401:106::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;70401:106:0;-1:-1:-1;;;;;70401:106:0;;:::i;62635:62::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62635:62:0;;;:::i;7559:46::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;7559:46:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;7559:46:0;;:::i;:::-;;;;;;;;;;;;;;;;;;63996:143;;5:9:-1;2:2;;;27:1;24;17:12;2:2;63996:143:0;;;:::i;64415:257::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;64415:257:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;64415:257:0;-1:-1:-1;;;;;64415:257:0;;:::i;7448:51::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;7448:51:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;7448:51:0;-1:-1:-1;;;;;7448:51:0;;:::i;62481:58::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62481:58:0;;;:::i;56847:138::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56847:138:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;56847:138:0;;;;;;;:::i;67275:482::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67275:482:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;;67275:482:0;;;;;;;;;;;;;;;;;:::i;55808:139::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;55808:139:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;55808:139:0;;;;;;-1:-1:-1;;;;;55808:139:0;;:::i;54553:49::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;54553:49:0;;;:::i;63740:139::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;63740:139:0;;;:::i;65186:299::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;65186:299:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;65186:299:0;-1:-1:-1;;;;;65186:299:0;;:::i;63334:290::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;63334:290:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;63334:290:0;-1:-1:-1;;;;;63334:290:0;;:::i;56121:127::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56121:127:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;56121:127:0;;:::i;62546:82::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62546:82:0;;;:::i;68684:694::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;68684:694:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;;68684:694:0;;;;;;;;;;;;;;;;;:::i;58022:230::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58022:230:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;58022:230:0;;;;;;-1:-1:-1;;;;;58022:230:0;;:::i;62420:54::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62420:54:0;;;:::i;66025:295::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;66025:295:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;66025:295:0;-1:-1:-1;;;;;66025:295:0;;:::i;64815:109::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;64815:109:0;;;:::i;70970:316::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;70970:316:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;70970:316:0;;;;;;;;;;;;;;;;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;70970:316:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;70970:316: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;-1:-1;70970:316:0;;-1:-1:-1;70970:316:0;-1:-1:-1;70970:316:0;:::i;7506:46::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;7506:46:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;7506:46:0;-1:-1:-1;;;;;7506:46:0;;:::i;7333:50::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;7333:50:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;7333:50:0;;:::i;7390:51::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;7390:51:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;7390:51:0;-1:-1:-1;;;;;7390:51:0;;:::i;62706:169::-;62796:22;62843:24;:22;:24::i;:::-;62836:31;;62706:169;;:::o;71294:579::-;71380:21;;;71391:9;71380:21;;;;;;;;;;26::-1;;;22:32;;;6:49;;71380:21:0;;;;;;71412:45;71424:4;62586:42;71380:21;71412:11;:45::i;:::-;71711:26;;71654:12;71695:43;;;:15;71711:26;71695:43;71711:26;71695:43;;;;:70;;-1:-1:-1;;;;;71695:43:0;;;;71751:9;;71654:12;71695:70;71654:12;71695:70;71751:9;71695:43;:70;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;71653:112:0;;;71781:7;71776:90;;71805:49;;-1:-1:-1;;;71805:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71776:90;71294:579;;;:::o;7706:39::-;;;-1:-1:-1;;;;;7706:39:0;;:::o;67989:363::-;54598:4;60789:27;54598:4;60803:12;:10;:12::i;:::-;60789:7;:27::i;:::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;68130:27:0;;::::1;68168:1;68130:27:::0;;;:16:::1;:27;::::0;;;;;;;:40;;-1:-1:-1;;;;;;68130:40:0;;::::1;::::0;;;68181:28;;::::1;::::0;;;:16:::1;:28:::0;;;;;:41;;;;::::1;::::0;;;68233:22;;;:11:::1;:22:::0;;;;;;:35;;;68286:58;68168:1;;68181:28;68130:27;68286:58:::1;::::0;68168:1;;68286:58:::1;67989:363:::0;;;:::o;35284:1119::-;35489:12;35514:29;;:::i;:::-;35546:152;;;;;;;;-1:-1:-1;;;;;35584:19:0;;-1:-1:-1;35584:19:0;;;:6;:19;;;;;;;;;35546:152;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35669:17;;;;;;35546:152;;35669:17;;;;35546:152;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;;35546:152:0;;-1:-1:-1;35514:184:0;-1:-1:-1;35733:45:0;35740:11;35514:184;35761:4;35767;35773;35733:6;:45::i;:::-;35711:128;;;;-1:-1:-1;;;35711:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35908:19:0;;;;;;:6;:19;;;;;;;;;35906:21;;;;;;35945:117;;;;;;;;;;;36009:10;;35908:19;35945:117;;36034:17;;;;35945:117;;;;;36034:17;;;;35945:117;1:33:-1;99:1;81:16;;;74:27;35945:117:0;;137:4:-1;117:14;;;-1:-1;;113:30;157:16;;;35945:117:0;;;;-1:-1:-1;35945:117:0;;-1:-1:-1;;;;35945:117:0;36173:12;36187:23;36222:4;-1:-1:-1;;;;;36214:18:0;36264:17;;36283:11;36247:48;;;;;;;30:3:-1;22:6;14;1:33;57:3;49:6;45:16;35:26;;36247:48:0;;;-1:-1:-1;;;;;36247:48:0;-1:-1:-1;;;;;36247:48:0;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;36247:48:0;;;36214:92;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;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;;;36214:92:0;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;36172:134:0;;;;36325:7;36317:48;;;;;-1:-1:-1;;;36317:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;36385:10;35284:1119;-1:-1:-1;;;;;;;;;35284:1119:0:o;66694:275::-;54598:4;60789:27;54598:4;60803:12;:10;:12::i;60789:27::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66852:26:0::1;::::0;;;:15:::1;:26;::::0;;;;;:45;;-1:-1:-1;;;;;;66852:45:0::1;-1:-1:-1::0;;;;;66852:45:0;::::1;::::0;;::::1;::::0;;;66913:48;;66852:45;;:26;;66913:48:::1;::::0;66852:26;66913:48:::1;66694:275:::0;;;:::o;32447:43::-;;;;;;;;;;;;;;-1:-1:-1;;;32447:43:0;;;;:::o;33457:101::-;33535:15;;33457:101;:::o;57174:114::-;57231:7;57258:12;;;:6;:12;;;;;:22;;;57174:114;;;;:::o;36411:109::-;-1:-1:-1;;;;;36500:12:0;36466:13;36500:12;;;:6;:12;;;;;;;36411:109::o;57550:227::-;57642:12;;;;:6;:12;;;;;:22;;;57634:45;;57666:12;:10;:12::i;57634:45::-;57626:105;;;;-1:-1:-1;;;57626:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57744:25;57755:4;57761:7;57744:10;:25::i;:::-;57550:227;;:::o;65640:121::-;65734:18;;-1:-1:-1;;;;;65734:18:0;65640:121;:::o;33566:161::-;33680:9;33566:161;:::o;58759:209::-;58857:12;:10;:12::i;:::-;-1:-1:-1;;;;;58846:23:0;:7;-1:-1:-1;;;;;58846:23:0;;58838:83;;;;-1:-1:-1;;;58838:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58934:26;58946:4;58952:7;58934:11;:26::i;73956:2611::-;74025:44;;:::i;:::-;74072:25;:9;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;74072:23:0;;-1:-1:-1;;;74072:25:0:i;:::-;74025:72;;74110:28;74141:30;:7;:28;:30::i;:::-;74110:61;;74333:16;74411:24;:7;:22;:24::i;:::-;74720:52;74756:15;74720:35;:52::i;:::-;74791:28;:7;:26;:28::i;:::-;74376:458;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;74376:458:0;;;;;-1:-1:-1;74376:458:0;;;26:21:-1;;;6:49;;74376:458:0;;;;;74352:493;;;;;;;;;-1:-1:-1;74880:24:0;;;:14;:24;;;;;;;74352:493;;-1:-1:-1;;74880:24:0;;:33;;-1:-1:-1;74858:123:0;;-1:-1:-1;74858:123:0;;;-1:-1:-1;;;74858:123:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74992:24;;;;:14;:24;;;;;:31;;-1:-1:-1;;74992:31:0;75019:4;74992:31;;;75036:40;;:::i;:::-;75079:20;:7;:18;:20::i;:::-;75036:63;;75110:32;;:::i;:::-;75145:16;:7;:14;:16::i;:::-;75110:51;;75232:17;75252:16;:34;75269:16;:3;:14;:16::i;:::-;-1:-1:-1;;;;;75252:34:0;;;;;;;;;;;;;;-1:-1:-1;75252:34:0;;;;-1:-1:-1;75319:23:0;75297:107;;;;-1:-1:-1;;;75297:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;75474:22:0;;;75417:24;75474:22;;;:11;:22;;;;;;;;;75444:63;;:15;:63;;;;;;;75589:29;:7;:27;:29::i;:::-;-1:-1:-1;;75589:111:0;:129;75567:216;;;;-1:-1:-1;;;75567:216:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75855:198;75900:17;:7;:15;:17::i;:::-;75936:15;75970:25;:7;:23;:25::i;:::-;76014:24;:7;:22;:24::i;:::-;75855:26;:198::i;:::-;75833:279;;;;;-1:-1:-1;;;75833:279:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;76165:271;76213:24;:7;:22;:24::i;:::-;76252:22;:7;:20;:22::i;:::-;76289:19;:7;:17;:19::i;:::-;76323:24;:7;:22;:24::i;:::-;76362:25;:7;:23;:25::i;:::-;76402:23;:7;:21;:23::i;:::-;76165:33;:271::i;:::-;76465:16;-1:-1:-1;;;;;76449:44:0;;76508:9;76532:16;:3;:14;:16::i;:::-;76449:110;;;-1:-1:-1;;;;;;76449:110:0;;;;;;;-1:-1:-1;;;;;76449:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;76449:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76449:110:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76449:110:0;;;;73956:2611;;;;;;;;;:::o;70401:106::-;70477:22;70494:4;70477:16;:22::i;:::-;70401:106;:::o;62635:62::-;62673:24;;;-1:-1:-1;;;62673:24:0;;;;;;;;;;;;62635:62;:::o;7559:46::-;;;;;;;;;;;;;;;:::o;63996:143::-;54598:4;60789:27;54598:4;60803:12;:10;:12::i;60789:27::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64092:39:::1;;;;;;;;;;;;;;-1:-1:-1::0;;;64092:39:0::1;;::::0;:19:::1;:39::i;64415:257::-:0;54598:4;60789:27;54598:4;60803:12;:10;:12::i;60789:27::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;64539:28:0;::::1;64531:79;;;;-1:-1:-1::0;;;64531:79:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;64621:12:0::1;:43:::0;;-1:-1:-1;;;;;;64621:43:0::1;-1:-1:-1::0;;;;;64621:43:0;;;::::1;::::0;;;::::1;::::0;;64415:257::o;7448:51::-;;;;;;;;;;;;-1:-1:-1;;;;;7448:51:0;;:::o;62481:58::-;62517:22;;;-1:-1:-1;;;62517:22:0;;;;;;;;;;;;62481:58;:::o;56847:138::-;56920:7;56947:12;;;:6;:12;;;;;:30;;56971:5;56947:30;:23;:30;:::i;:::-;56940:37;;56847:138;;;;;:::o;67275:482::-;62673:24;;;-1:-1:-1;;;62673:24:0;;;;;;;;;;;;60789:27;62673:24;60803:12;:10;:12::i;60789:27::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;67535:27:0;;::::1;67574:1;67535:27:::0;;;:16:::1;:27;::::0;;;;;::::1;:41:::0;:100;::::1;;;-1:-1:-1::0;;;;;;67593:28:0;;::::1;67633:1;67593:28:::0;;;:16:::1;:28;::::0;;;;;::::1;:42:::0;67535:100:::1;67513:182;;;::::0;;-1:-1:-1;;;67513:182:0;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;67706:43;67716:9;67727:10;67739:9;67706;:43::i;:::-;67275:482:::0;;;;:::o;55808:139::-;55877:4;55901:12;;;:6;:12;;;;;:38;;55931:7;55901:38;:29;:38;:::i;54553:49::-;54598:4;54553:49;:::o;63740:139::-;54598:4;60789:27;54598:4;60803:12;:10;:12::i;60789:27::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63835:36:::1;;;;;;;;;;;;;;-1:-1:-1::0;;;63835:36:0::1;;::::0;:16:::1;:36::i;65186:299::-:0;54598:4;60789:27;54598:4;60803:12;:10;:12::i;60789:27::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;65322:34:0;::::1;65314:91;;;;-1:-1:-1::0;;;65314:91:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;65416:18:0::1;:61:::0;;-1:-1:-1;;;;;;65416:61:0::1;-1:-1:-1::0;;;;;65416:61:0;;;::::1;::::0;;;::::1;::::0;;65186:299::o;63334:290::-;32113:6;;;;32112:7;32104:34;;;;;-1:-1:-1;;;32104:34:0;;;;;;;;;;;;-1:-1:-1;;;32104:34:0;;;;;;;;;;;;;;;63441:37:::1;;;;;;;;;;;;;;-1:-1:-1::0;;;63441:37:0::1;;::::0;:17:::1;:37::i;:::-;63489:36;;;;;;;;;;;;;;-1:-1:-1::0;;;63489:36:0::1;;::::0;:16:::1;:36::i;:::-;63536:38;54598:4;63567:6:::0;63536:10:::1;:38::i;:::-;62673:24;::::0;;-1:-1:-1;;;62673:24:0;;;;;;;;::::1;::::0;;;63585:31:::1;::::0;63609:6;63585:10:::1;:31::i;:::-;-1:-1:-1::0;32161:6:0;:13;;-1:-1:-1;;32161:13:0;32170:4;32161:13;;;63334:290::o;56121:127::-;56184:7;56211:12;;;:6;:12;;;;;:29;;:27;:29::i;62546:82::-;62586:42;62546:82;:::o;68684:694::-;54598:4;60789:27;54598:4;60803:12;:10;:12::i;60789:27::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;68906:27:0;;::::1;68882:21;68906:27:::0;;;:16:::1;:27;::::0;;;;;;;;68967:28;;::::1;::::0;;:16:::1;:28:::0;;;;;;;::::1;69012:30:::0;;;;;;;;;;;68906:27;;::::1;::::0;68967:28;;69012:30:::1;:44:::0;69008:173:::1;;-1:-1:-1::0;;;;;69073:30:0;::::1;69114:1;69073:30:::0;;;:16:::1;:30;::::0;;;;;;;:43;;-1:-1:-1;;;;;;69073:43:0::1;::::0;;69131:11:::1;:25:::0;;;;;:38;69008:173:::1;-1:-1:-1::0;;;;;69197:31:0;;::::1;69240:1;69197:31:::0;;;:16:::1;:31;::::0;;;;;::::1;:45:::0;69193:122:::1;;-1:-1:-1::0;;;;;69259:31:0;::::1;69301:1;69259:31:::0;;;:16:::1;:31;::::0;;;;:44;;-1:-1:-1;;;;;;69259:44:0::1;::::0;;69193:122:::1;69327:43;69337:9;69348:10;69360:9;69327;:43::i;:::-;60863:1;;68684:694:::0;;;;:::o;58022:230::-;58115:12;;;;:6;:12;;;;;:22;;;58107:45;;58139:12;:10;:12::i;58107:45::-;58099:106;;;;-1:-1:-1;;;58099:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62420:54;62454:20;;;-1:-1:-1;;;62454:20:0;;;;;;;;;;;;62420:54;:::o;66025:295::-;54598:4;60789:27;54598:4;60803:12;:10;:12::i;60789:27::-;60831:10;60767:85;;;;;-1:-1:-1;;;60767:85:0;;;;;;;;;;;;-1:-1:-1;;60767:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;66168:36:0;::::1;66160:94;;;;-1:-1:-1::0;;;66160:94:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;66265:24:0::1;:47:::0;;-1:-1:-1;;;;;;66265:47:0::1;-1:-1:-1::0;;;;;66265:47:0;;;::::1;::::0;;;::::1;::::0;;66025:295::o;64815:109::-;64903:12;;-1:-1:-1;;;;;64903:12:0;64815:109;:::o;70970:316::-;-1:-1:-1;;;;;71136:26:0;;62586:42;71136:26;;71114:112;;;;-1:-1:-1;;;71114:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71237:41;71249:4;71255:9;71266:11;;71237:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;71237:11:0;;-1:-1:-1;;;71237:41:0:i;7506:46::-;;;;;;;;;;;;;:::o;7333:50::-;;;;;;;;;;;;-1:-1:-1;;;;;7333:50:0;;:::o;7390:51::-;;;;;;;;;;;;-1:-1:-1;;;;;7390:51:0;;:::o;60989:641::-;61060:22;61104:10;61126:4;61104:27;61100:499;;;61148:18;61169:8;;61148:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;;;61208:8:0;61419:17;61413:24;-1:-1:-1;;;;;61387:134:0;;-1:-1:-1;61247:289:0;;-1:-1:-1;61247:289:0;;-1:-1:-1;61577:10:0;60989:641;:::o;71881:1021::-;-1:-1:-1;;;;;72034:22:0;;;72014:17;72034:22;;;:11;:22;;;;;;;;;72089:16;:27;;;;;;;72034:22;;72089:27;:43;;;;:77;;-1:-1:-1;72152:14:0;;;72089:77;72067:161;;;;-1:-1:-1;;;72067:161:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72239:24;72266:26;;;:15;:26;;;;;;-1:-1:-1;;;;;72266:26:0;72325:30;72303:116;;;;-1:-1:-1;;;72303:116:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;72452:18:0;;72430:98;;;;;-1:-1:-1;;;72430:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;72557:16;-1:-1:-1;;;;;72541:44:0;;72600:12;:10;:12::i;:::-;72627:4;72646:9;72670:11;72541:151;;;;;;;;;;;;;-1:-1:-1;;;;;72541:151:0;-1:-1:-1;;;;;72541:151:0;;;;;;-1:-1:-1;;;;;72541:151:0;-1:-1:-1;;;;;72541:151:0;;;;;;-1:-1:-1;;;;;72541:151:0;-1:-1:-1;;;;;72541:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;72541:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;72541:151:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72541:151:0;;;;72703:21;72738:4;72744:9;72755:11;72727:40;;;;;;-1:-1:-1;;;;;72727:40:0;-1:-1:-1;;;;;72727:40:0;;;;;;-1:-1:-1;;;;;72727:40:0;-1:-1:-1;;;;;72727:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;72727:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72727:40:0;;;26:21:-1;;;-1:-1;;22:32;6:49;;72727:40:0;;;72778:12;;;72815:24;;-1:-1:-1;;;62454:20:0;;;;;;;;;;;;;49:4:-1;72854:29:0;;;;;;;;;;;;;;;;;;;;72727:40;;-1:-1:-1;;;;;;72778:12:0;;;;-1:-1:-1;72778:22:0;;-1:-1:-1;72815:24:0;;;;;-1:-1:-1;62454:20:0;-1:-1:-1;72727:40:0;;-1:-1:-1;72854:29:0;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;72854:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;72854:29:0;;;72778:116;;;;;;;;;;;;;-1:-1:-1;;;;;72778:116:0;-1:-1:-1;;;;;72778:116:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;72778:116:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;72778:116:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72778:116:0;;;;71881:1021;;;;;;:::o;36946:486::-;37124:4;-1:-1:-1;;;;;37149:20:0;;37141:70;;;;-1:-1:-1;;;37141:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37265:159;37293:47;37312:27;37332:6;37312:19;:27::i;:::-;37293:18;:47::i;:::-;37359:4;37382;37405;37265:159;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;37265:159:0;;;;;;;;-1:-1:-1;;;;;37242:182:0;:6;-1:-1:-1;;;;;37242:182:0;;37222:202;;36946:486;;;;;;;:::o;60002:188::-;60076:12;;;;:6;:12;;;;;:33;;60101:7;60076:33;:24;:33;:::i;:::-;60072:111;;;60158:12;:10;:12::i;:::-;-1:-1:-1;;;;;60131:40:0;60149:7;-1:-1:-1;;;;;60131:40:0;60143:4;60131:40;;;;;;;;;;60002:188;;:::o;60198:192::-;60273:12;;;;:6;:12;;;;;:36;;60301:7;60273:36;:27;:36;:::i;:::-;60269:114;;;60358:12;:10;:12::i;:::-;-1:-1:-1;;;;;60331:40:0;60349:7;-1:-1:-1;;;;;60331:40:0;60343:4;60331:40;;;;;;;;;;60198:192;;:::o;20042:274::-;20134:18;;:::i;:::-;20170:38;20211:53;:30;:4;:28;:30::i;:::-;:51;:53::i;:::-;20284:24;;;;;;;;;;;;;20042:274;-1:-1:-1;;;20042:274:0:o;22219:143::-;22299:12;22329:25;:7;:12;;;22342:1;22329:15;;;;;;;;;;;;;;:23;:25::i;20608:131::-;20682:7;20707:24;:7;:12;;;20720:1;20707:15;;;;;;;;;;;;;;:22;:24::i;28159:827::-;28280:25;;;;;;;;;-1:-1:-1;28280:25:0;;28320:8;;28250:12;;28280:25;28320:12;28316:638;;28349:12;28376:14;28399:26;28420:1;28423;28399:20;:26::i;:::-;28393:33;;;-1:-1:-1;28457:1:0;28445:13;;;:30;;;28462:8;:13;;28474:1;28462:13;28445:30;28441:349;;;28531:1;28516;:8;28527:1;28516:12;:16;28506:27;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;28506:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;28506:27:0;87:42:-1;143:17;;-1:-1;28506:27:0;;28496:37;;28552:16;28571:26;28592:1;28595;28571:20;:26::i;:::-;28552:45;;28629:9;28616:7;28624:1;28616:10;;;;;;;;;;;:22;-1:-1:-1;;;;;28616:22:0;;;;;;;;;28666:1;28657:10;;28441:349;;;;28743:1;28728;:8;28739:1;28728:12;:16;28718:27;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;28718:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;28718:27:0;87:42:-1;143:17;;-1:-1;28718:27:0;;28708:37;;28773:1;28764:10;;28441:349;28811:18;;;28806:137;28835:7;:14;28831:1;:18;28806:137;;;28888:39;28913:6;28909:10;;:1;:10;28922:1;28909:14;28925:1;28888:20;:39::i;:::-;28875:7;28883:1;28875:10;;;;;;;;;;;:52;-1:-1:-1;;;;;28875:52:0;;;;;;;;-1:-1:-1;28851:3:0;;28806:137;;;;28316:638;;28971:7;28159:827;-1:-1:-1;;28159:827:0:o;22514:135::-;22592:7;22617:24;:7;:12;;;22630:1;22617:15;;;;;;;21175:890;21245:22;;:::i;:::-;21292:25;:7;:12;;;21305:1;21292:15;;;;;;;:25;21278:11;;;:39;21326:36;;:::i;:::-;21365:23;:7;:11;;;:21;:23::i;:::-;21326:62;;21403:20;:11;:18;:20::i;:::-;21399:579;;;21477:20;:11;:18;:20::i;:::-;21462:35;;21399:579;;;21605:11;;;;21661:17;;21579:23;;-1:-1:-1;;21661:21:0;21651:32;;;2:2:-1;;;;27:1;24;17:12;2:2;21651:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;21651:32:0;87:42:-1;143:17;;-1:-1;21651:32:0;;21629:54;;21696:14;21723:15;21795:10;21791:2;21787:19;21777:29;;21843:6;21837:4;21833:17;21822:28;;21877:36;21882:6;21890:7;21899:6;:13;21877:4;:36::i;:::-;21941:27;:18;:6;:16;:18::i;:27::-;21926:42;;-1:-1:-1;;;;21399:579:0;22007:27;22026:7;22007:18;:27::i;:::-;21988:16;;;:46;-1:-1:-1;21175:890:0;;;:::o;22807:218::-;22869:10;;:::i;:::-;22892:32;;:::i;:::-;22927:24;:7;:12;;;22940:1;22927:15;;;;;;;;;;;;;;:22;:24::i;:::-;22952:7;:16;;;22927:42;;;;;;;;;;;;;;22892:77;;22987:30;;;;;;;;22991:7;22987:30;;;;23000:16;:7;:14;:16::i;:::-;22987:30;;22980:37;22807:218;-1:-1:-1;;;22807:218:0:o;23053:123::-;23111:7;23136:32;23156:3;:8;;;23165:1;23156:11;;;;;;;;;;;;;;23136:19;:32::i;22370:136::-;22449:7;22474:24;:7;:12;;;22487:1;22474:15;;;;;;;22685:114;22780:11;;;;22685:114::o;22073:138::-;22148:12;22178:25;:7;:12;;;22191:1;22178:15;;;;;;;21027:140;21101:7;21134:24;:7;:12;;;21147:1;21134:15;;;;;;;24358:2772;24529:4;24546:29;;:::i;:::-;24578:35;24598:14;24578:19;:35::i;:::-;24546:67;;24624:38;24665:22;24682:4;24665:16;:22::i;:::-;24624:63;-1:-1:-1;24700:24:0;;24808:4;24790:15;24700:24;24875:28;24891:11;24875:15;:28::i;:::-;24855:48;;24918:4;:11;24933:1;24918:16;24914:61;;;24958:5;24951:12;;;;;;;;;;;24914:61;24992:9;24987:2102;25011:11;:18;25007:1;:22;24987:2102;;;25065:4;:11;25055:7;:21;25051:74;;;25104:5;25097:12;;;;;;;;;;;;25051:74;25155:36;25176:11;25188:1;25176:14;;;;;;;;;;;;;;25155:20;:36::i;:::-;25141:50;;25231:11;25221:22;;;;;;25210:7;:33;25206:86;;25271:5;25264:12;;;;;;;;;;;;25206:86;25324:32;25341:11;25353:1;25341:14;;;;;;;25324:32;25306:50;;25377:15;:22;25403:2;25377:28;25373:1705;;;25441:4;:11;25430:7;:22;25426:349;;;25595:5;25585:16;;;;;;25517:38;25535:15;25551:2;25535:19;;;;;;;25517:38;25507:49;;;;;;:94;25477:279;;;25659:4;25652:11;;;;;;;;;;;;25477:279;25727:5;25720:12;;;;;;;;;;;;25477:279;25795:20;25824:4;25829:7;25824:13;;;;;;;;;;;;;;;-1:-1:-1;25878:2:0;25861:19;;25857:80;;;25912:5;25905:12;;;;;;;;;;;;;25857:80;25995:55;26018:15;26034:14;26018:31;;;;;;;;;;;;;;;;25995:22;:55::i;:::-;25965:104;-1:-1:-1;;26099:1:0;26088:12;;;;;25373:1705;;;26126:15;:22;26152:1;26126:27;26122:956;;;26174:17;26194:154;26235:37;26253:15;26269:1;26253:18;;;;;;;26235:37;26295:4;26322:7;26194:18;:154::i;:::-;26174:174;;26394:4;:11;26381:9;26371:7;:19;:34;26367:393;;;26580:5;26570:16;;;;;;26503:37;26521:15;26537:1;26521:18;;;;;;;26503:37;26493:48;;;;;;:93;26463:278;;;26644:4;26637:11;;;;;;;;;;;;;26463:278;26712:5;26705:12;;;;;;;;;;;;;26463:278;26818:14;26814:75;;26864:5;26857:12;;;;;;;;;;;;;26814:75;26920:9;26909:20;;;;26966:42;26989:15;27005:1;26989:18;;;;;;;26966:42;26958:51;-1:-1:-1;26122:956:0;;-1:-1:-1;26122:956:0;;25031:3;;24987:2102;;;;27106:5;27099:12;;;;;;;;;24358:2772;;;;;;;:::o;20747:129::-;20819:7;20844:24;:7;:12;;;20857:1;20844:15;;;;;;;20884:135;20953:7;20986:24;:7;:12;;;20999:1;20986:15;;;;;;;20324:132;20399:7;20424:24;:7;:12;;;20437:1;20424:15;;;;;;;20464:136;20537:12;20567:25;:7;:12;;;20580:1;20567:15;;;;;;;76575:770;76940:18;;:45;;;-1:-1:-1;;;76940:45:0;;;;;;;;;;76842:18;;;;-1:-1:-1;;;;;76940:18:0;;;;:31;;:45;;;;;;;;;;;;;;;:18;:45;;;2:2:-1;;;;27:1;24;17:12;2:2;76940:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76940:45:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;76940:45:0;;;;;;;;;-1:-1:-1;76940:45:0;-1:-1:-1;77020:257:0;77177:27;:11;76940:45;77177:27;:15;:27;:::i;:::-;77048:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;77048:61:0;;;;;;;77020:104;;;;;;77223:10;77252;77020:257;:138;:257;:::i;:::-;76998:339;;;;;-1:-1:-1;;;76998:339:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76575:770;;;;;;;;:::o;23448:117::-;23506:12;23536:21;:3;:8;;;:19;:21::i;33089:360::-;32570:112;;;;;;;;;;;;;;;;;32550:139;;;;;;;33270:22;;;;;;33327:14;;;;;;;;;;;;-1:-1:-1;;;33327:14:0;;;;;;32550:139;33311:32;33370:4;33402:12;:10;:12::i;:::-;33200:230;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33200:230:0;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;33200:230:0;;;;;;33176:265;;;;;33158:15;:283;-1:-1:-1;33089:360:0:o;43768:149::-;43842:7;43885:22;43889:3;43901:5;43885:3;:22::i;69386:694::-;69576:3;69538:26;;;:15;:26;;;;;;-1:-1:-1;;;;;69538:26:0;69516:134;;;;-1:-1:-1;;;69516:134:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;69663:27:0;;;;;;;:16;:27;;;;;;;;:40;;;;;-1:-1:-1;;;;;;69663:40:0;;;;;;;;69714:28;;;:16;:28;;;;;:40;;;;;;;;;;69765:22;;;:11;:22;;;;;;:34;;;69817:45;69790:9;;69663:40;:27;69817:45;;;69899:44;;;-1:-1:-1;;;;;69899:44:0;;;;;;;;;;;;;;;;;;69875:21;69899:44;;;;;;;;26:21:-1;;;22:32;;6:49;;69899:44:0;;;;;;;69954:12;;69991:24;;-1:-1:-1;;;62517:22:0;;;;;;;;;;;;;70030:31;;;;;;;;;;;;;;;;;;;;;;;69899:44;;69954:12;;;;:22;;69991:24;;;;;62517:22;;69899:44;;70030:31;;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;70030:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;70030:31:0;;;69954:118;;;;;;;;;;;;;-1:-1:-1;;;;;69954:118:0;-1:-1:-1;;;;;69954:118:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;69954:118:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;69954:118:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;43063:158:0;43143:4;43167:46;43177:3;-1:-1:-1;;;;;43197:14:0;;43167:9;:46::i;60561:159::-;60670:10;60653:58;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;60653:58:0;;;;;;;;;;;26:21:-1;;;-1:-1;;22:32;6:49;;60653:58:0;;;;;;60633:79;;;;-1:-1:-1;60633:10:0;;-1:-1:-1;60633:79:0;;;;-1:-1:-1;60633:79:0;:::i;32930:151::-;32113:6;;;;32112:7;32104:34;;;;;-1:-1:-1;;;32104:34:0;;;;;;;;;;;;-1:-1:-1;;;32104:34:0;;;;;;;;;;;;;;;33048:25:::1;33068:4;33048:19;:25::i;43307:117::-:0;43370:7;43397:19;43405:3;43397:7;:19::i;36528:410::-;36638:7;34604:100;;;;;;;;;;;;;;;;;34584:127;;;;;;36792:6;:12;;;36827:6;:11;;;36871:6;:24;;;36861:35;;;;;;36711:204;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36711:204:0;-1:-1:-1;;;;;36711:204:0;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;36711:204:0;;;36683:247;;;;;;36663:267;;36528:410;;;:::o;34096:258::-;34195:7;34297:20;:18;:20::i;:::-;34319:11;34268:63;;;;;;-1:-1:-1;;;34268:63:0;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;34268:63:0;;;34240:106;;;;;;34220:126;;34096:258;;;:::o;42509:143::-;42579:4;42603:41;42608:3;-1:-1:-1;;;;;42628:14:0;;42603:4;:41::i;42828:149::-;42901:4;42925:44;42933:3;-1:-1:-1;;;;;42953:14:0;;42925:7;:44::i;9409:225::-;9470:14;;:::i;:::-;-1:-1:-1;9598:28:0;;;;;;;;;9606:11;;9598:28;;9563:4;9553:15;;;9598:28;;;;9409:225;;;:::o;10852:523::-;10912:16;10949:12;10956:4;10949:6;:12::i;:::-;10941:21;;12:1:-1;9;2:12;10941:21:0;10975:10;10988:14;10997:4;10988:8;:14::i;:::-;10975:27;;11013:23;11053:5;11039:20;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;11039:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;11013:46;;11072:11;11100:27;11115:4;:11;;;11100:14;:27::i;:::-;11086:11;;;;:41;;-1:-1:-1;11138:12:0;;11161:181;11182:5;11178:1;:9;11161:181;;;11219:19;11231:6;11219:11;:19::i;:::-;11209:29;;11265:24;;;;;;;;11273:7;11265:24;;;;11282:6;11265:24;;;11253:6;11260:1;11253:9;;;;;;;;;;;;;;;;;:36;11314:16;;;;11189:3;;11161:181;;;-1:-1:-1;11361:6:0;;10852:523;-1:-1:-1;;;;;10852:523:0:o;14858:383::-;14952:8;;14919:12;;14944:21;;12:1:-1;9;2:12;14944:21:0;14979:11;14992:8;15004:21;15020:4;15004:15;:21::i;:::-;14978:47;;;;15036:19;15068:3;15058:14;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;15058:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;15058::0;87:42:-1;143:17;;-1:-1;15058:14:0;-1:-1:-1;15036:36:0;-1:-1:-1;15147:4:0;15143:17;;15183:26;15188:6;15143:17;15205:3;15183:4;:26::i;:::-;-1:-1:-1;15227:6:0;14858:383;-1:-1:-1;;;;14858:383:0:o;14039:471::-;14124:8;;14099:4;;14124:12;;;;:30;;-1:-1:-1;14140:8:0;;14152:2;-1:-1:-1;14140:14:0;14124:30;14116:39;;12:1:-1;9;2:12;14116:39:0;14169:11;14182:8;14194:21;14210:4;14194:15;:21::i;:::-;14284:13;;14168:47;;-1:-1:-1;14168:47:0;-1:-1:-1;14383:2:0;14375:11;;14372:2;;;14441;14437:12;;;14432:3;14428:22;14416:35;;14496:6;14039:471;-1:-1:-1;;;;14039:471:0:o;28994:264::-;29102:6;29175:1;29171;:5;:10;:64;;29231:4;29217:3;29225:1;29221;:5;29217:10;;;;;;;;;;;;;;29211:24;;;;;;29171:64;;;29204:4;29190:3;29198:1;29194;:5;29190:10;;;;;;;;;;;;;;29184:24;;;;;;29171:64;29146:104;;;28994:264;-1:-1:-1;;;28994:264:0:o;11482:342::-;11563:8;;11542:4;;11559:31;;-1:-1:-1;11585:5:0;11578:12;;11559:31;11639:11;;;;11702:13;;11603:11;11694:22;;8200:4;11743:24;;11739:55;;;11789:5;11782:12;;;;;;11739:55;-1:-1:-1;11812:4:0;;11482:342;-1:-1:-1;;;11482:342:0:o;19319:717::-;19392:8;19388:21;;19402:7;;19388:21;19469:201;18918:2;19476:16;;19469:201;;19568:10;;19555:24;;18918:2;19610:16;;;;19641:17;;;;-1:-1:-1;;19494:16:0;19469:201;;;19857:10;;19929:11;;18918:2;19783:15;;;;19775:3;:24;-1:-1:-1;;19775:28:0;19869:9;;19853:26;;;19925:22;;19996:21;;;;19983:35;;19823:206::o;13835:196::-;13967:8;;13898:7;;13979:2;13967:14;13959:23;;12:1:-1;9;2:12;13959:23:0;14010:12;14017:4;14010:6;:12::i;12809:353::-;12873:12;12898:19;12930:4;:8;;;12920:19;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;12920:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;12920:19:0;87:42:-1;143:17;;-1:-1;12920:19:0;;12898:41;;12954:6;:13;12971:1;12954:18;12950:37;;;12981:6;-1:-1:-1;12974:13:0;;12950:37;13008:8;13068:6;13062:4;13058:17;13051:24;;13098:32;13103:4;:11;;;13116:3;13121:4;:8;;;13098:4;:32::i;:::-;-1:-1:-1;13148:6:0;12809:353;-1:-1:-1;;12809:353:0:o;14550:300::-;14669:8;;14616:4;;14681:2;14669:14;14661:23;;12:1:-1;9;2:12;14661:23:0;-1:-1:-1;14733:11:0;;;14747:1;14733:15;14793:13;;14550:300::o;27138:978::-;27291:7;;27524:24;27551:35;27567:18;27551:15;:35::i;:::-;27524:62;;27597:23;27633:11;:18;27623:29;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;27623:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;27623:29:0;87:42:-1;143:17;;-1:-1;27623:29:0;-1:-1:-1;27597:55:0;-1:-1:-1;27779:7:0;27762:170;27802:11;:18;27792:7;:28;27788:1;:32;27762:170;;;27842:17;27862:4;27867:1;27862:7;;;;;;;;;;;;;;;;27842:27;;27910:10;27884;27899:7;27895:1;:11;27884:23;;;;;;;;;;;:36;-1:-1:-1;;;;;27884:36:0;;;;;;;;-1:-1:-1;;27822:3:0;;27762:170;;;;27984:10;27974:21;;;;;;27958:11;27948:22;;;;;;:47;27944:144;;;28018:11;:18;28012:24;;27944:144;;;28075:1;28069:7;;27944:144;-1:-1:-1;28105:3:0;;27138:978;-1:-1:-1;;;;;27138:978:0:o;1420:136::-;1478:7;1505:43;1509:1;1512;1505:43;;;;;;;;;;;;;;;;;:3;:43::i;29350:1128::-;29508:4;29548:2;29533:5;:12;:17;;;;;;:22;29525:55;;;;;-1:-1:-1;;;29525:55:0;;;;;;;;;;;;-1:-1:-1;;;29525:55:0;;;;;;;;;;;;;;;29591:19;29628:2;29613:5;:12;:17;;;;;;29591:39;;29790:11;29785:1;:16;29777:5;:24;29769:58;;;;;-1:-1:-1;;;29769:58:0;;;;;;;;;;;;-1:-1:-1;;;29769:58:0;;;;;;;;;;;;;;;29840:20;29894:4;29926:2;29909:520;29935:5;:12;29930:1;:17;29909:520;;30023:13;;;30017:20;;-1:-1:-1;30080:1:0;30072:5;:9;30068:316;;30171:12;30185;30154:44;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;30154:44:0;;;30122:95;;;;;;30107:110;;30068:316;;;30322:12;30336;30305:44;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;30305:44:0;;;30273:95;;;;;;30258:110;;30068:316;30416:1;30408:5;:9;;-1:-1:-1;29954:2:0;29949:7;29909:520;;;-1:-1:-1;30446:24:0;;;;29350:1128;-1:-1:-1;;;;;;29350:1128:0:o;42051:204::-;42146:18;;42118:7;;42146:26;-1:-1:-1;42138:73:0;;;;-1:-1:-1;;;42138:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42229:3;:11;;42241:5;42229:18;;;;;;;;;;;;;;;;42222:25;;42051:204;;;;:::o;41383:129::-;41456:4;41480:19;;;:12;;;;;:19;;;;;;:24;;;41383:129::o;41598:109::-;41681:18;;41598:109::o;39163:414::-;39226:4;39248:21;39258:3;39263:5;39248:9;:21::i;:::-;39243:327;;-1:-1:-1;27:10;;39:1;23:18;;;45:23;;39286:11:0;:23;;;;;;;;;;;;;39469:18;;39447:19;;;:12;;;:19;;;;;;:40;;;;39502:11;;39243:327;-1:-1:-1;39553:5:0;39546:12;;39753:1544;39819:4;39958:19;;;:12;;;:19;;;;;;39994:15;;39990:1300;;40429:18;;-1:-1:-1;;40380:14:0;;;;40429:22;;;;40356:21;;40429:3;;:22;;40716;;;;;;;;;;;;;;40696:42;;40862:9;40833:3;:11;;40845:13;40833:26;;;;;;;;;;;;;;;;;;;:38;;;;40939:23;;;40981:1;40939:12;;;:23;;;;;;40965:17;;;40939:43;;41091:17;;40939:3;;41091:17;;;;;;;;;;;;;;;;;;;;;;41186:3;:12;;:19;41199:5;41186:19;;;;;;;;;;;41179:26;;;41229:4;41222:11;;;;;;;;39990:1300;41273:5;41266:12;;;;;15354:422;15436:8;;15415:4;;15432:27;;-1:-1:-1;15458:1:0;15451:8;;15432:27;15472:10;15485:1;15472:14;;15497:12;15526:27;15541:4;:11;;;15526:14;:27::i;:::-;15512:11;;;;15592:8;;15512:41;;;;-1:-1:-1;15578:22:0;15611:133;15628:6;15618:7;:16;15611:133;;;15670:20;15682:7;15670:11;:20::i;:::-;15725:7;;;;;15660:30;;;;15611:133;;;-1:-1:-1;15763:5:0;;15354:422;-1:-1:-1;;;15354:422:0:o;17210:552::-;17348:13;;17269:4;;17340:22;;8106:4;17389:26;;17385:369;;;17438:1;17431:8;;;;;17385:369;8153:4;17459:25;;;:83;;-1:-1:-1;8200:4:0;17489:25;;;;;:52;;-1:-1:-1;8247:4:0;17518:23;;17489:52;17455:299;;;17564:1;17557:8;;;;;17455:299;8200:4;17585:24;;17581:173;;;-1:-1:-1;;17650:35:0;;-1:-1:-1;17643:42:0;;17581:173;-1:-1:-1;;17721:33:0;;-1:-1:-1;17714:40:0;;15828:1327;15986:13;;15884:4;;;;15978:22;;8106:4;16027:26;;16023:1098;;;16078:1;16068:11;;16023:1098;;;8153:4;16109:25;;16105:1016;;;-1:-1:-1;;16159:30:0;;;-1:-1:-1;16105:1016:0;;;8200:4;16211:24;;16207:914;;;16306:4;16299:5;16295:16;16386:1;16378:6;16374:14;16364:24;;16544:7;16540:2;16536:16;16531:3;16527:26;16518:6;16512:13;16508:46;16642:1;16633:7;16629:15;16620:7;16616:29;16605:40;;;;16261:399;;;8247:4;16692:23;;16688:433;;;-1:-1:-1;;16742:28:0;;;-1:-1:-1;16688:433:0;;;16914:1;16902:14;;;;16955:13;16983:2;16979:16;;;16869:4;16979:16;16974:3;16970:26;16951:46;;17066:29;;;-1:-1:-1;;17066:29:0;;15828:1327;-1:-1:-1;;15828:1327:0:o;10303:271::-;10372:4;10378;10395:11;10409:27;10424:4;:11;;;10409:14;:27::i;:::-;10461:11;;;;10503:8;;10461:20;;;;10503:17;;;10303:271;-1:-1:-1;;;10303:271:0:o;17923:780::-;17996:8;17992:21;;18006:7;;17992:21;18073:201;8285:2;18080:16;;18073:201;;18172:10;;18159:24;;8285:2;18214:16;;;;18245:17;;;;-1:-1:-1;;18098:16:0;18073:201;;;18290:7;;18286:410;;18501:10;;18577:11;;8285:2;18419:15;;;;18411:3;:24;-1:-1:-1;;18411:28:0;18513:9;;18497:26;;;18573:22;;18648:21;;;;18635:35;;17923:780::o;1859:192::-;1945:7;1981:12;1973:6;;;;1965:29;;;;-1:-1:-1;;;1965:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1965:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2017:5:0;;;1859:192::o;61758:15590::-;;;;;;;;;;;;;;;-1:-1:-1;;;;;61758:15590:0;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61758:15590:0;;;-1:-1:-1;61758:15590:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;
Swarm Source
ipfs://5dff4876821f39240dc4251f6b691bc1a025719014956c8de7463f264b9c9776
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.