Token
veNFT (veNFT)
ERC721
Overview
Max Total Supply
0 veNFT
Holders
0
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Balance
0 veNFTLoading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
VotingEscrow
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity)
/** *Submitted for verification at sepolia-optimism.etherscan.io on 2023-11-01 */ // SPDX-License-Identifier: GPL-3.0-or-later // File: contracts/interfaces/IVotingEscrow.sol pragma solidity 0.8.13; interface IVotingEscrow { struct Point { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block } function token() external view returns (address); function team() external returns (address); function epoch() external view returns (uint); function point_history(uint loc) external view returns (Point memory); function user_point_history(uint tokenId, uint loc) external view returns (Point memory); function user_point_epoch(uint tokenId) external view returns (uint); function ownerOf(uint) external view returns (address); function isApprovedOrOwner(address, uint) external view returns (bool); function transferFrom(address, address, uint) external; function voting(uint tokenId) external; function abstain(uint tokenId) external; function attach(uint tokenId) external; function detach(uint tokenId) external; function checkpoint() external; function deposit_for(uint tokenId, uint value) external; function create_lock_for(uint, uint, address) external returns (uint); function balanceOfNFT(uint) external view returns (uint); function totalSupply() external view returns (uint); } // File: contracts/interfaces/IVeArtProxy.sol pragma solidity 0.8.13; interface IVeArtProxy { function _tokenURI(uint _tokenId, uint _balanceOf, uint _locked_end, uint _value) external pure returns (string memory output); } // File: contracts/interfaces/IERC20.sol pragma solidity 0.8.13; interface IERC20 { function totalSupply() external view returns (uint256); function transfer(address recipient, uint amount) external returns (bool); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function balanceOf(address) external view returns (uint); function transferFrom(address sender, address recipient, uint amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } // File: openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: openzeppelin-contracts/contracts/governance/utils/IVotes.sol // OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.0; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). */ function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); /** * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 blockNumber) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; } // File: openzeppelin-contracts/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: openzeppelin-contracts/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: contracts/VotingEscrow.sol pragma solidity 0.8.13; /// @title Voting Escrow /// @notice veNFT implementation that escrows ERC-20 tokens in the form of an ERC-721 NFT /// @notice Votes have a weight depending on time, so that users are committed to the future of (whatever they are voting for) /// @author Modified from Solidly (https://github.com/solidlyexchange/solidly/blob/master/contracts/ve.sol) /// @author Modified from Curve (https://github.com/curvefi/curve-dao-contracts/blob/master/contracts/VotingEscrow.vy) /// @author Modified from Nouns DAO (https://github.com/withtally/my-nft-dao-project/blob/main/contracts/ERC721Checkpointable.sol) /// @dev Vote weight decays linearly over time. Lock time cannot be more than `MAXTIME` (4 years). contract VotingEscrow is IERC721, IERC721Metadata, IVotes { enum DepositType { DEPOSIT_FOR_TYPE, CREATE_LOCK_TYPE, INCREASE_LOCK_AMOUNT, INCREASE_UNLOCK_TIME, MERGE_TYPE } struct LockedBalance { int128 amount; uint end; } struct Point { int128 bias; int128 slope; // # -dweight / dt uint ts; uint blk; // block } /* We cannot really do block numbers per se b/c slope is per time, not per block * and per block could be fairly bad b/c Ethereum changes blocktimes. * What we can do is to extrapolate ***At functions */ /// @notice A checkpoint for marking delegated tokenIds from a given timestamp struct Checkpoint { uint timestamp; uint[] tokenIds; } /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Deposit( address indexed provider, uint tokenId, uint value, uint indexed locktime, DepositType deposit_type, uint ts ); event Withdraw(address indexed provider, uint tokenId, uint value, uint ts); event Supply(uint prevSupply, uint supply); /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ address public immutable token; address public voter; address public team; address public artProxy; mapping(uint => Point) public point_history; // epoch -> unsigned point /// @dev Mapping of interface id to bool about whether or not it's supported mapping(bytes4 => bool) internal supportedInterfaces; /// @dev ERC165 interface ID of ERC165 bytes4 internal constant ERC165_INTERFACE_ID = 0x01ffc9a7; /// @dev ERC165 interface ID of ERC721 bytes4 internal constant ERC721_INTERFACE_ID = 0x80ac58cd; /// @dev ERC165 interface ID of ERC721Metadata bytes4 internal constant ERC721_METADATA_INTERFACE_ID = 0x5b5e139f; /// @dev Current count of token uint internal tokenId; /// @notice Contract constructor /// @param token_addr `VELO` token address constructor(address token_addr, address art_proxy) { token = token_addr; voter = msg.sender; team = msg.sender; artProxy = art_proxy; point_history[0].blk = block.number; point_history[0].ts = block.timestamp; supportedInterfaces[ERC165_INTERFACE_ID] = true; supportedInterfaces[ERC721_INTERFACE_ID] = true; supportedInterfaces[ERC721_METADATA_INTERFACE_ID] = true; // mint-ish emit Transfer(address(0), address(this), tokenId); // burn-ish emit Transfer(address(this), address(0), tokenId); } /*////////////////////////////////////////////////////////////// MODIFIERS //////////////////////////////////////////////////////////////*/ /// @dev reentrancy guard uint8 internal constant _not_entered = 1; uint8 internal constant _entered = 2; uint8 internal _entered_state = 1; modifier nonreentrant() { require(_entered_state == _not_entered); _entered_state = _entered; _; _entered_state = _not_entered; } /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string constant public name = "veNFT"; string constant public symbol = "veNFT"; string constant public version = "1.0.0"; uint8 constant public decimals = 18; function setTeam(address _team) external { require(msg.sender == team); team = _team; } function setArtProxy(address _proxy) external { require(msg.sender == team); artProxy = _proxy; } /// @dev Returns current token URI metadata /// @param _tokenId Token ID to fetch URI for. function tokenURI(uint _tokenId) external view returns (string memory) { require(idToOwner[_tokenId] != address(0), "Query for nonexistent token"); LockedBalance memory _locked = locked[_tokenId]; return IVeArtProxy(artProxy)._tokenURI( _tokenId, _balanceOfNFT(_tokenId, block.timestamp), _locked.end, uint(int256(_locked.amount)) ); } /*////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE //////////////////////////////////////////////////////////////*/ /// @dev Mapping from NFT ID to the address that owns it. mapping(uint => address) internal idToOwner; /// @dev Mapping from owner address to count of his tokens. mapping(address => uint) internal ownerToNFTokenCount; /// @dev Returns the address of the owner of the NFT. /// @param _tokenId The identifier for an NFT. function ownerOf(uint _tokenId) public view returns (address) { return idToOwner[_tokenId]; } /// @dev Returns the number of NFTs owned by `_owner`. /// Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid. /// @param _owner Address for whom to query the balance. function _balance(address _owner) internal view returns (uint) { return ownerToNFTokenCount[_owner]; } /// @dev Returns the number of NFTs owned by `_owner`. /// Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid. /// @param _owner Address for whom to query the balance. function balanceOf(address _owner) external view returns (uint) { return _balance(_owner); } /*////////////////////////////////////////////////////////////// ERC721 APPROVAL STORAGE //////////////////////////////////////////////////////////////*/ /// @dev Mapping from NFT ID to approved address. mapping(uint => address) internal idToApprovals; /// @dev Mapping from owner address to mapping of operator addresses. mapping(address => mapping(address => bool)) internal ownerToOperators; mapping(uint => uint) public ownership_change; /// @dev Get the approved address for a single NFT. /// @param _tokenId ID of the NFT to query the approval of. function getApproved(uint _tokenId) external view returns (address) { return idToApprovals[_tokenId]; } /// @dev Checks if `_operator` is an approved operator for `_owner`. /// @param _owner The address that owns the NFTs. /// @param _operator The address that acts on behalf of the owner. function isApprovedForAll(address _owner, address _operator) external view returns (bool) { return (ownerToOperators[_owner])[_operator]; } /*////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ /// @dev Set or reaffirm the approved address for an NFT. The zero address indicates there is no approved address. /// Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner. /// Throws if `_tokenId` is not a valid NFT. (NOTE: This is not written the EIP) /// Throws if `_approved` is the current owner. (NOTE: This is not written the EIP) /// @param _approved Address to be approved for the given NFT ID. /// @param _tokenId ID of the token to be approved. function approve(address _approved, uint _tokenId) public { address owner = idToOwner[_tokenId]; // Throws if `_tokenId` is not a valid NFT require(owner != address(0)); // Throws if `_approved` is the current owner require(_approved != owner); // Check requirements bool senderIsOwner = (idToOwner[_tokenId] == msg.sender); bool senderIsApprovedForAll = (ownerToOperators[owner])[msg.sender]; require(senderIsOwner || senderIsApprovedForAll); // Set the approval idToApprovals[_tokenId] = _approved; emit Approval(owner, _approved, _tokenId); } /// @dev Enables or disables approval for a third party ("operator") to manage all of /// `msg.sender`'s assets. It also emits the ApprovalForAll event. /// Throws if `_operator` is the `msg.sender`. (NOTE: This is not written the EIP) /// @notice This works even if sender doesn't own any tokens at the time. /// @param _operator Address to add to the set of authorized operators. /// @param _approved True if the operators is approved, false to revoke approval. function setApprovalForAll(address _operator, bool _approved) external { // Throws if `_operator` is the `msg.sender` assert(_operator != msg.sender); ownerToOperators[msg.sender][_operator] = _approved; emit ApprovalForAll(msg.sender, _operator, _approved); } /* TRANSFER FUNCTIONS */ /// @dev Clear an approval of a given address /// Throws if `_owner` is not the current owner. function _clearApproval(address _owner, uint _tokenId) internal { // Throws if `_owner` is not the current owner assert(idToOwner[_tokenId] == _owner); if (idToApprovals[_tokenId] != address(0)) { // Reset approvals idToApprovals[_tokenId] = address(0); } } /// @dev Returns whether the given spender can transfer a given token ID /// @param _spender address of the spender to query /// @param _tokenId uint ID of the token to be transferred /// @return bool whether the msg.sender is approved for the given token ID, is an operator of the owner, or is the owner of the token function _isApprovedOrOwner(address _spender, uint _tokenId) internal view returns (bool) { address owner = idToOwner[_tokenId]; bool spenderIsOwner = owner == _spender; bool spenderIsApproved = _spender == idToApprovals[_tokenId]; bool spenderIsApprovedForAll = (ownerToOperators[owner])[_spender]; return spenderIsOwner || spenderIsApproved || spenderIsApprovedForAll; } function isApprovedOrOwner(address _spender, uint _tokenId) external view returns (bool) { return _isApprovedOrOwner(_spender, _tokenId); } /// @dev Exeute transfer of a NFT. /// Throws unless `msg.sender` is the current owner, an authorized operator, or the approved /// address for this NFT. (NOTE: `msg.sender` not allowed in internal function so pass `_sender`.) /// Throws if `_to` is the zero address. /// Throws if `_from` is not the current owner. /// Throws if `_tokenId` is not a valid NFT. function _transferFrom( address _from, address _to, uint _tokenId, address _sender ) internal { require(attachments[_tokenId] == 0 && !voted[_tokenId], "attached"); // Check requirements require(_isApprovedOrOwner(_sender, _tokenId)); // Clear approval. Throws if `_from` is not the current owner _clearApproval(_from, _tokenId); // Remove NFT. Throws if `_tokenId` is not a valid NFT _removeTokenFrom(_from, _tokenId); // auto re-delegate _moveTokenDelegates(delegates(_from), delegates(_to), _tokenId); // Add NFT _addTokenTo(_to, _tokenId); // Set the block of ownership transfer (for Flash NFT protection) ownership_change[_tokenId] = block.number; // Log the transfer emit Transfer(_from, _to, _tokenId); } /// @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT. /// Throws if `_from` is not the current owner. /// Throws if `_to` is the zero address. /// Throws if `_tokenId` is not a valid NFT. /// @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else /// they maybe be permanently lost. /// @param _from The current owner of the NFT. /// @param _to The new owner. /// @param _tokenId The NFT to transfer. function transferFrom( address _from, address _to, uint _tokenId ) external { _transferFrom(_from, _to, _tokenId, msg.sender); } /// @dev Transfers the ownership of an NFT from one address to another address. /// Throws unless `msg.sender` is the current owner, an authorized operator, or the /// approved address for this NFT. /// Throws if `_from` is not the current owner. /// Throws if `_to` is the zero address. /// Throws if `_tokenId` is not a valid NFT. /// If `_to` is a smart contract, it calls `onERC721Received` on `_to` and throws if /// the return value is not `bytes4(keccak256("onERC721Received(address,address,uint,bytes)"))`. /// @param _from The current owner of the NFT. /// @param _to The new owner. /// @param _tokenId The NFT to transfer. function safeTransferFrom( address _from, address _to, uint _tokenId ) external { safeTransferFrom(_from, _to, _tokenId, ""); } function _isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint size; assembly { size := extcodesize(account) } return size > 0; } /// @dev Transfers the ownership of an NFT from one address to another address. /// Throws unless `msg.sender` is the current owner, an authorized operator, or the /// approved address for this NFT. /// Throws if `_from` is not the current owner. /// Throws if `_to` is the zero address. /// Throws if `_tokenId` is not a valid NFT. /// If `_to` is a smart contract, it calls `onERC721Received` on `_to` and throws if /// the return value is not `bytes4(keccak256("onERC721Received(address,address,uint,bytes)"))`. /// @param _from The current owner of the NFT. /// @param _to The new owner. /// @param _tokenId The NFT to transfer. /// @param _data Additional data with no specified format, sent in call to `_to`. function safeTransferFrom( address _from, address _to, uint _tokenId, bytes memory _data ) public { _transferFrom(_from, _to, _tokenId, msg.sender); if (_isContract(_to)) { // Throws if transfer destination is a contract which does not implement 'onERC721Received' try IERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) returns (bytes4 response) { if (response != IERC721Receiver(_to).onERC721Received.selector) { revert("ERC721: ERC721Receiver rejected tokens"); } } catch (bytes memory reason) { if (reason.length == 0) { revert('ERC721: transfer to non ERC721Receiver implementer'); } else { assembly { revert(add(32, reason), mload(reason)) } } } } } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ /// @dev Interface identification is specified in ERC-165. /// @param _interfaceID Id of the interface function supportsInterface(bytes4 _interfaceID) external view returns (bool) { return supportedInterfaces[_interfaceID]; } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ /// @dev Mapping from owner address to mapping of index to tokenIds mapping(address => mapping(uint => uint)) internal ownerToNFTokenIdList; /// @dev Mapping from NFT ID to index of owner mapping(uint => uint) internal tokenToOwnerIndex; /// @dev Get token by index function tokenOfOwnerByIndex(address _owner, uint _tokenIndex) external view returns (uint) { return ownerToNFTokenIdList[_owner][_tokenIndex]; } /// @dev Add a NFT to an index mapping to a given address /// @param _to address of the receiver /// @param _tokenId uint ID Of the token to be added function _addTokenToOwnerList(address _to, uint _tokenId) internal { uint current_count = _balance(_to); ownerToNFTokenIdList[_to][current_count] = _tokenId; tokenToOwnerIndex[_tokenId] = current_count; } /// @dev Add a NFT to a given address /// Throws if `_tokenId` is owned by someone. function _addTokenTo(address _to, uint _tokenId) internal { // Throws if `_tokenId` is owned by someone assert(idToOwner[_tokenId] == address(0)); // Change the owner idToOwner[_tokenId] = _to; // Update owner token index tracking _addTokenToOwnerList(_to, _tokenId); // Change count tracking ownerToNFTokenCount[_to] += 1; } /// @dev Function to mint tokens /// Throws if `_to` is zero address. /// Throws if `_tokenId` is owned by someone. /// @param _to The address that will receive the minted tokens. /// @param _tokenId The token id to mint. /// @return A boolean that indicates if the operation was successful. function _mint(address _to, uint _tokenId) internal returns (bool) { // Throws if `_to` is zero address assert(_to != address(0)); // checkpoint for gov _moveTokenDelegates(address(0), delegates(_to), _tokenId); // Add NFT. Throws if `_tokenId` is owned by someone _addTokenTo(_to, _tokenId); emit Transfer(address(0), _to, _tokenId); return true; } /// @dev Remove a NFT from an index mapping to a given address /// @param _from address of the sender /// @param _tokenId uint ID Of the token to be removed function _removeTokenFromOwnerList(address _from, uint _tokenId) internal { // Delete uint current_count = _balance(_from) - 1; uint current_index = tokenToOwnerIndex[_tokenId]; if (current_count == current_index) { // update ownerToNFTokenIdList ownerToNFTokenIdList[_from][current_count] = 0; // update tokenToOwnerIndex tokenToOwnerIndex[_tokenId] = 0; } else { uint lastTokenId = ownerToNFTokenIdList[_from][current_count]; // Add // update ownerToNFTokenIdList ownerToNFTokenIdList[_from][current_index] = lastTokenId; // update tokenToOwnerIndex tokenToOwnerIndex[lastTokenId] = current_index; // Delete // update ownerToNFTokenIdList ownerToNFTokenIdList[_from][current_count] = 0; // update tokenToOwnerIndex tokenToOwnerIndex[_tokenId] = 0; } } /// @dev Remove a NFT from a given address /// Throws if `_from` is not the current owner. function _removeTokenFrom(address _from, uint _tokenId) internal { // Throws if `_from` is not the current owner assert(idToOwner[_tokenId] == _from); // Change the owner idToOwner[_tokenId] = address(0); // Update owner token index tracking _removeTokenFromOwnerList(_from, _tokenId); // Change count tracking ownerToNFTokenCount[_from] -= 1; } function _burn(uint _tokenId) internal { require(_isApprovedOrOwner(msg.sender, _tokenId), "caller is not owner nor approved"); address owner = ownerOf(_tokenId); // Clear approval approve(address(0), _tokenId); // checkpoint for gov _moveTokenDelegates(delegates(owner), address(0), _tokenId); // Remove token _removeTokenFrom(msg.sender, _tokenId); emit Transfer(owner, address(0), _tokenId); } /*////////////////////////////////////////////////////////////// ESCROW STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint => uint) public user_point_epoch; mapping(uint => Point[1000000000]) public user_point_history; // user -> Point[user_epoch] mapping(uint => LockedBalance) public locked; uint public epoch; mapping(uint => int128) public slope_changes; // time -> signed slope change uint public supply; uint internal constant WEEK = 1 weeks; uint internal constant MAXTIME = 4 * 365 * 86400; int128 internal constant iMAXTIME = 4 * 365 * 86400; uint internal constant MULTIPLIER = 1 ether; /*////////////////////////////////////////////////////////////// ESCROW LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Get the most recently recorded rate of voting power decrease for `_tokenId` /// @param _tokenId token of the NFT /// @return Value of the slope function get_last_user_slope(uint _tokenId) external view returns (int128) { uint uepoch = user_point_epoch[_tokenId]; return user_point_history[_tokenId][uepoch].slope; } /// @notice Get the timestamp for checkpoint `_idx` for `_tokenId` /// @param _tokenId token of the NFT /// @param _idx User epoch number /// @return Epoch time of the checkpoint function user_point_history__ts(uint _tokenId, uint _idx) external view returns (uint) { return user_point_history[_tokenId][_idx].ts; } /// @notice Get timestamp when `_tokenId`'s lock finishes /// @param _tokenId User NFT /// @return Epoch time of the lock end function locked__end(uint _tokenId) external view returns (uint) { return locked[_tokenId].end; } /// @notice Record global and per-user data to checkpoint /// @param _tokenId NFT token ID. No user checkpoint if 0 /// @param old_locked Pevious locked amount / end lock time for the user /// @param new_locked New locked amount / end lock time for the user function _checkpoint( uint _tokenId, LockedBalance memory old_locked, LockedBalance memory new_locked ) internal { Point memory u_old; Point memory u_new; int128 old_dslope = 0; int128 new_dslope = 0; uint _epoch = epoch; if (_tokenId != 0) { // Calculate slopes and biases // Kept at zero when they have to if (old_locked.end > block.timestamp && old_locked.amount > 0) { u_old.slope = old_locked.amount / iMAXTIME; u_old.bias = u_old.slope * int128(int256(old_locked.end - block.timestamp)); } if (new_locked.end > block.timestamp && new_locked.amount > 0) { u_new.slope = new_locked.amount / iMAXTIME; u_new.bias = u_new.slope * int128(int256(new_locked.end - block.timestamp)); } // Read values of scheduled changes in the slope // old_locked.end can be in the past and in the future // new_locked.end can ONLY by in the FUTURE unless everything expired: than zeros old_dslope = slope_changes[old_locked.end]; if (new_locked.end != 0) { if (new_locked.end == old_locked.end) { new_dslope = old_dslope; } else { new_dslope = slope_changes[new_locked.end]; } } } Point memory last_point = Point({bias: 0, slope: 0, ts: block.timestamp, blk: block.number}); if (_epoch > 0) { last_point = point_history[_epoch]; } uint last_checkpoint = last_point.ts; // initial_last_point is used for extrapolation to calculate block number // (approximately, for *At methods) and save them // as we cannot figure that out exactly from inside the contract Point memory initial_last_point = last_point; uint block_slope = 0; // dblock/dt if (block.timestamp > last_point.ts) { block_slope = (MULTIPLIER * (block.number - last_point.blk)) / (block.timestamp - last_point.ts); } // If last point is already recorded in this block, slope=0 // But that's ok b/c we know the block in such case // Go over weeks to fill history and calculate what the current point is { uint t_i = (last_checkpoint / WEEK) * WEEK; for (uint i = 0; i < 255; ++i) { // Hopefully it won't happen that this won't get used in 5 years! // If it does, users will be able to withdraw but vote weight will be broken t_i += WEEK; int128 d_slope = 0; if (t_i > block.timestamp) { t_i = block.timestamp; } else { d_slope = slope_changes[t_i]; } last_point.bias -= last_point.slope * int128(int256(t_i - last_checkpoint)); last_point.slope += d_slope; if (last_point.bias < 0) { // This can happen last_point.bias = 0; } if (last_point.slope < 0) { // This cannot happen - just in case last_point.slope = 0; } last_checkpoint = t_i; last_point.ts = t_i; last_point.blk = initial_last_point.blk + (block_slope * (t_i - initial_last_point.ts)) / MULTIPLIER; _epoch += 1; if (t_i == block.timestamp) { last_point.blk = block.number; break; } else { point_history[_epoch] = last_point; } } } epoch = _epoch; // Now point_history is filled until t=now if (_tokenId != 0) { // If last point was in this block, the slope change has been applied already // But in such case we have 0 slope(s) last_point.slope += (u_new.slope - u_old.slope); last_point.bias += (u_new.bias - u_old.bias); if (last_point.slope < 0) { last_point.slope = 0; } if (last_point.bias < 0) { last_point.bias = 0; } } // Record the changed point into history point_history[_epoch] = last_point; if (_tokenId != 0) { // Schedule the slope changes (slope is going down) // We subtract new_user_slope from [new_locked.end] // and add old_user_slope to [old_locked.end] if (old_locked.end > block.timestamp) { // old_dslope was <something> - u_old.slope, so we cancel that old_dslope += u_old.slope; if (new_locked.end == old_locked.end) { old_dslope -= u_new.slope; // It was a new deposit, not extension } slope_changes[old_locked.end] = old_dslope; } if (new_locked.end > block.timestamp) { if (new_locked.end > old_locked.end) { new_dslope -= u_new.slope; // old slope disappeared at this point slope_changes[new_locked.end] = new_dslope; } // else: we recorded it already in old_dslope } // Now handle user history uint user_epoch = user_point_epoch[_tokenId] + 1; user_point_epoch[_tokenId] = user_epoch; u_new.ts = block.timestamp; u_new.blk = block.number; user_point_history[_tokenId][user_epoch] = u_new; } } /// @notice Deposit and lock tokens for a user /// @param _tokenId NFT that holds lock /// @param _value Amount to deposit /// @param unlock_time New time when to unlock the tokens, or 0 if unchanged /// @param locked_balance Previous locked amount / timestamp /// @param deposit_type The type of deposit function _deposit_for( uint _tokenId, uint _value, uint unlock_time, LockedBalance memory locked_balance, DepositType deposit_type ) internal { LockedBalance memory _locked = locked_balance; uint supply_before = supply; supply = supply_before + _value; LockedBalance memory old_locked; (old_locked.amount, old_locked.end) = (_locked.amount, _locked.end); // Adding to existing lock, or if a lock is expired - creating a new one _locked.amount += int128(int256(_value)); if (unlock_time != 0) { _locked.end = unlock_time; } locked[_tokenId] = _locked; // Possibilities: // Both old_locked.end could be current or expired (>/< block.timestamp) // value == 0 (extend lock) or value > 0 (add to lock or extend lock) // _locked.end > block.timestamp (always) _checkpoint(_tokenId, old_locked, _locked); address from = msg.sender; if (_value != 0 && deposit_type != DepositType.MERGE_TYPE) { assert(IERC20(token).transferFrom(from, address(this), _value)); } emit Deposit(from, _tokenId, _value, _locked.end, deposit_type, block.timestamp); emit Supply(supply_before, supply_before + _value); } function block_number() external view returns (uint) { return block.number; } /// @notice Record global data to checkpoint function checkpoint() external { _checkpoint(0, LockedBalance(0, 0), LockedBalance(0, 0)); } /// @notice Deposit `_value` tokens for `_tokenId` and add to the lock /// @dev Anyone (even a smart contract) can deposit for someone else, but /// cannot extend their locktime and deposit for a brand new user /// @param _tokenId lock NFT /// @param _value Amount to add to user's lock function deposit_for(uint _tokenId, uint _value) external nonreentrant { LockedBalance memory _locked = locked[_tokenId]; require(_value > 0); // dev: need non-zero value require(_locked.amount > 0, 'No existing lock found'); require(_locked.end > block.timestamp, 'Cannot add to expired lock. Withdraw'); _deposit_for(_tokenId, _value, 0, _locked, DepositType.DEPOSIT_FOR_TYPE); } /// @notice Deposit `_value` tokens for `_to` and lock for `_lock_duration` /// @param _value Amount to deposit /// @param _lock_duration Number of seconds to lock tokens for (rounded down to nearest week) /// @param _to Address to deposit function _create_lock(uint _value, uint _lock_duration, address _to) internal returns (uint) { uint unlock_time = (block.timestamp + _lock_duration) / WEEK * WEEK; // Locktime is rounded down to weeks require(_value > 0); // dev: need non-zero value require(unlock_time > block.timestamp, 'Can only lock until time in the future'); require(unlock_time <= block.timestamp + MAXTIME, 'Voting lock can be 4 years max'); ++tokenId; uint _tokenId = tokenId; _mint(_to, _tokenId); _deposit_for(_tokenId, _value, unlock_time, locked[_tokenId], DepositType.CREATE_LOCK_TYPE); return _tokenId; } /// @notice Deposit `_value` tokens for `msg.sender` and lock for `_lock_duration` /// @param _value Amount to deposit /// @param _lock_duration Number of seconds to lock tokens for (rounded down to nearest week) function create_lock(uint _value, uint _lock_duration) external nonreentrant returns (uint) { return _create_lock(_value, _lock_duration, msg.sender); } /// @notice Deposit `_value` tokens for `_to` and lock for `_lock_duration` /// @param _value Amount to deposit /// @param _lock_duration Number of seconds to lock tokens for (rounded down to nearest week) /// @param _to Address to deposit function create_lock_for(uint _value, uint _lock_duration, address _to) external nonreentrant returns (uint) { return _create_lock(_value, _lock_duration, _to); } /// @notice Deposit `_value` additional tokens for `_tokenId` without modifying the unlock time /// @param _value Amount of tokens to deposit and add to the lock function increase_amount(uint _tokenId, uint _value) external nonreentrant { assert(_isApprovedOrOwner(msg.sender, _tokenId)); LockedBalance memory _locked = locked[_tokenId]; assert(_value > 0); // dev: need non-zero value require(_locked.amount > 0, 'No existing lock found'); require(_locked.end > block.timestamp, 'Cannot add to expired lock. Withdraw'); _deposit_for(_tokenId, _value, 0, _locked, DepositType.INCREASE_LOCK_AMOUNT); } /// @notice Extend the unlock time for `_tokenId` /// @param _lock_duration New number of seconds until tokens unlock function increase_unlock_time(uint _tokenId, uint _lock_duration) external nonreentrant { assert(_isApprovedOrOwner(msg.sender, _tokenId)); LockedBalance memory _locked = locked[_tokenId]; uint unlock_time = (block.timestamp + _lock_duration) / WEEK * WEEK; // Locktime is rounded down to weeks require(_locked.end > block.timestamp, 'Lock expired'); require(_locked.amount > 0, 'Nothing is locked'); require(unlock_time > _locked.end, 'Can only increase lock duration'); require(unlock_time <= block.timestamp + MAXTIME, 'Voting lock can be 4 years max'); _deposit_for(_tokenId, 0, unlock_time, _locked, DepositType.INCREASE_UNLOCK_TIME); } /// @notice Withdraw all tokens for `_tokenId` /// @dev Only possible if the lock has expired function withdraw(uint _tokenId) external nonreentrant { assert(_isApprovedOrOwner(msg.sender, _tokenId)); require(attachments[_tokenId] == 0 && !voted[_tokenId], "attached"); LockedBalance memory _locked = locked[_tokenId]; require(block.timestamp >= _locked.end, "The lock didn't expire"); uint value = uint(int256(_locked.amount)); locked[_tokenId] = LockedBalance(0,0); uint supply_before = supply; supply = supply_before - value; // old_locked can have either expired <= timestamp or zero end // _locked has only 0 end // Both can have >= 0 amount _checkpoint(_tokenId, _locked, LockedBalance(0,0)); assert(IERC20(token).transfer(msg.sender, value)); // Burn the NFT _burn(_tokenId); emit Withdraw(msg.sender, _tokenId, value, block.timestamp); emit Supply(supply_before, supply_before - value); } /*/////////////////////////////////////////////////////////////// GAUGE VOTING STORAGE //////////////////////////////////////////////////////////////*/ // The following ERC20/minime-compatible methods are not real balanceOf and supply! // They measure the weights for the purpose of voting, so they don't represent // real coins. /// @notice Binary search to estimate timestamp for block number /// @param _block Block to find /// @param max_epoch Don't go beyond this epoch /// @return Approximate timestamp for block function _find_block_epoch(uint _block, uint max_epoch) internal view returns (uint) { // Binary search uint _min = 0; uint _max = max_epoch; for (uint i = 0; i < 128; ++i) { // Will be always enough for 128-bit numbers if (_min >= _max) { break; } uint _mid = (_min + _max + 1) / 2; if (point_history[_mid].blk <= _block) { _min = _mid; } else { _max = _mid - 1; } } return _min; } /// @notice Get the current voting power for `_tokenId` /// @dev Adheres to the ERC20 `balanceOf` interface for Aragon compatibility /// @param _tokenId NFT for lock /// @param _t Epoch time to return voting power at /// @return User voting power function _balanceOfNFT(uint _tokenId, uint _t) internal view returns (uint) { uint _epoch = user_point_epoch[_tokenId]; if (_epoch == 0) { return 0; } else { Point memory last_point = user_point_history[_tokenId][_epoch]; last_point.bias -= last_point.slope * int128(int256(_t) - int256(last_point.ts)); if (last_point.bias < 0) { last_point.bias = 0; } return uint(int256(last_point.bias)); } } function balanceOfNFT(uint _tokenId) external view returns (uint) { if (ownership_change[_tokenId] == block.number) return 0; return _balanceOfNFT(_tokenId, block.timestamp); } function balanceOfNFTAt(uint _tokenId, uint _t) external view returns (uint) { return _balanceOfNFT(_tokenId, _t); } /// @notice Measure voting power of `_tokenId` at block height `_block` /// @dev Adheres to MiniMe `balanceOfAt` interface: https://github.com/Giveth/minime /// @param _tokenId User's wallet NFT /// @param _block Block to calculate the voting power at /// @return Voting power function _balanceOfAtNFT(uint _tokenId, uint _block) internal view returns (uint) { // Copying and pasting totalSupply code because Vyper cannot pass by // reference yet assert(_block <= block.number); // Binary search uint _min = 0; uint _max = user_point_epoch[_tokenId]; for (uint i = 0; i < 128; ++i) { // Will be always enough for 128-bit numbers if (_min >= _max) { break; } uint _mid = (_min + _max + 1) / 2; if (user_point_history[_tokenId][_mid].blk <= _block) { _min = _mid; } else { _max = _mid - 1; } } Point memory upoint = user_point_history[_tokenId][_min]; uint max_epoch = epoch; uint _epoch = _find_block_epoch(_block, max_epoch); Point memory point_0 = point_history[_epoch]; uint d_block = 0; uint d_t = 0; if (_epoch < max_epoch) { Point memory point_1 = point_history[_epoch + 1]; d_block = point_1.blk - point_0.blk; d_t = point_1.ts - point_0.ts; } else { d_block = block.number - point_0.blk; d_t = block.timestamp - point_0.ts; } uint block_time = point_0.ts; if (d_block != 0) { block_time += (d_t * (_block - point_0.blk)) / d_block; } upoint.bias -= upoint.slope * int128(int256(block_time - upoint.ts)); if (upoint.bias >= 0) { return uint(uint128(upoint.bias)); } else { return 0; } } function balanceOfAtNFT(uint _tokenId, uint _block) external view returns (uint) { return _balanceOfAtNFT(_tokenId, _block); } /// @notice Calculate total voting power at some point in the past /// @param _block Block to calculate the total voting power at /// @return Total voting power at `_block` function totalSupplyAt(uint _block) external view returns (uint) { assert(_block <= block.number); uint _epoch = epoch; uint target_epoch = _find_block_epoch(_block, _epoch); Point memory point = point_history[target_epoch]; uint dt = 0; if (target_epoch < _epoch) { Point memory point_next = point_history[target_epoch + 1]; if (point.blk != point_next.blk) { dt = ((_block - point.blk) * (point_next.ts - point.ts)) / (point_next.blk - point.blk); } } else { if (point.blk != block.number) { dt = ((_block - point.blk) * (block.timestamp - point.ts)) / (block.number - point.blk); } } // Now dt contains info on how far are we beyond point return _supply_at(point, point.ts + dt); } /// @notice Calculate total voting power at some point in the past /// @param point The point (bias/slope) to start search from /// @param t Time to calculate the total voting power at /// @return Total voting power at that time function _supply_at(Point memory point, uint t) internal view returns (uint) { Point memory last_point = point; uint t_i = (last_point.ts / WEEK) * WEEK; for (uint i = 0; i < 255; ++i) { t_i += WEEK; int128 d_slope = 0; if (t_i > t) { t_i = t; } else { d_slope = slope_changes[t_i]; } last_point.bias -= last_point.slope * int128(int256(t_i - last_point.ts)); if (t_i == t) { break; } last_point.slope += d_slope; last_point.ts = t_i; } if (last_point.bias < 0) { last_point.bias = 0; } return uint(uint128(last_point.bias)); } function totalSupply() external view returns (uint) { return totalSupplyAtT(block.timestamp); } /// @notice Calculate total voting power /// @dev Adheres to the ERC20 `totalSupply` interface for Aragon compatibility /// @return Total voting power function totalSupplyAtT(uint t) public view returns (uint) { uint _epoch = epoch; Point memory last_point = point_history[_epoch]; return _supply_at(last_point, t); } /*/////////////////////////////////////////////////////////////// GAUGE VOTING LOGIC //////////////////////////////////////////////////////////////*/ mapping(uint => uint) public attachments; mapping(uint => bool) public voted; function setVoter(address _voter) external { require(msg.sender == voter); voter = _voter; } function voting(uint _tokenId) external { require(msg.sender == voter); voted[_tokenId] = true; } function abstain(uint _tokenId) external { require(msg.sender == voter); voted[_tokenId] = false; } function attach(uint _tokenId) external { require(msg.sender == voter); attachments[_tokenId] = attachments[_tokenId] + 1; } function detach(uint _tokenId) external { require(msg.sender == voter); attachments[_tokenId] = attachments[_tokenId] - 1; } function merge(uint _from, uint _to) external { require(attachments[_from] == 0 && !voted[_from], "attached"); require(_from != _to); require(_isApprovedOrOwner(msg.sender, _from)); require(_isApprovedOrOwner(msg.sender, _to)); LockedBalance memory _locked0 = locked[_from]; LockedBalance memory _locked1 = locked[_to]; uint value0 = uint(int256(_locked0.amount)); uint end = _locked0.end >= _locked1.end ? _locked0.end : _locked1.end; locked[_from] = LockedBalance(0, 0); _checkpoint(_from, _locked0, LockedBalance(0, 0)); _burn(_from); _deposit_for(_to, value0, end, _locked1, DepositType.MERGE_TYPE); } /*/////////////////////////////////////////////////////////////// DAO VOTING STORAGE //////////////////////////////////////////////////////////////*/ /// @notice The EIP-712 typehash for the contract's domain bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); /// @notice The EIP-712 typehash for the delegation struct used by the contract bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); /// @notice A record of each accounts delegate mapping(address => address) private _delegates; uint public constant MAX_DELEGATES = 1024; // avoid too much gas /// @notice A record of delegated token checkpoints for each account, by index mapping(address => mapping(uint32 => Checkpoint)) public checkpoints; /// @notice The number of checkpoints for each account mapping(address => uint32) public numCheckpoints; /// @notice A record of states for signing / validating signatures mapping(address => uint) public nonces; /** * @notice Overrides the standard `Comp.sol` delegates mapping to return * the delegator's own address if they haven't delegated. * This avoids having to delegate to oneself. */ function delegates(address delegator) public view returns (address) { address current = _delegates[delegator]; return current == address(0) ? delegator : current; } /** * @notice Gets the current votes balance for `account` * @param account The address to get votes balance * @return The number of current votes for `account` */ function getVotes(address account) external view returns (uint) { uint32 nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; } uint[] storage _tokenIds = checkpoints[account][nCheckpoints - 1].tokenIds; uint votes = 0; for (uint i = 0; i < _tokenIds.length; i++) { uint tId = _tokenIds[i]; votes = votes + _balanceOfNFT(tId, block.timestamp); } return votes; } function getPastVotesIndex(address account, uint timestamp) public view returns (uint32) { uint32 nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; } // First check most recent balance if (checkpoints[account][nCheckpoints - 1].timestamp <= timestamp) { return (nCheckpoints - 1); } // Next check implicit zero balance if (checkpoints[account][0].timestamp > timestamp) { return 0; } uint32 lower = 0; uint32 upper = nCheckpoints - 1; while (upper > lower) { uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow Checkpoint storage cp = checkpoints[account][center]; if (cp.timestamp == timestamp) { return center; } else if (cp.timestamp < timestamp) { lower = center; } else { upper = center - 1; } } return lower; } function getPastVotes(address account, uint timestamp) public view returns (uint) { uint32 _checkIndex = getPastVotesIndex(account, timestamp); // Sum votes uint[] storage _tokenIds = checkpoints[account][_checkIndex].tokenIds; uint votes = 0; for (uint i = 0; i < _tokenIds.length; i++) { uint tId = _tokenIds[i]; // Use the provided input timestamp here to get the right decay votes = votes + _balanceOfNFT(tId, timestamp); } return votes; } function getPastTotalSupply(uint256 timestamp) external view returns (uint) { return totalSupplyAtT(timestamp); } /*/////////////////////////////////////////////////////////////// DAO VOTING LOGIC //////////////////////////////////////////////////////////////*/ function _moveTokenDelegates( address srcRep, address dstRep, uint _tokenId ) internal { if (srcRep != dstRep && _tokenId > 0) { if (srcRep != address(0)) { uint32 srcRepNum = numCheckpoints[srcRep]; uint[] storage srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].tokenIds : checkpoints[srcRep][0].tokenIds; uint32 nextSrcRepNum = _findWhatCheckpointToWrite(srcRep); uint[] storage srcRepNew = checkpoints[srcRep][ nextSrcRepNum ].tokenIds; // All the same except _tokenId for (uint i = 0; i < srcRepOld.length; i++) { uint tId = srcRepOld[i]; if (tId != _tokenId) { srcRepNew.push(tId); } } numCheckpoints[srcRep] = srcRepNum + 1; } if (dstRep != address(0)) { uint32 dstRepNum = numCheckpoints[dstRep]; uint[] storage dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].tokenIds : checkpoints[dstRep][0].tokenIds; uint32 nextDstRepNum = _findWhatCheckpointToWrite(dstRep); uint[] storage dstRepNew = checkpoints[dstRep][ nextDstRepNum ].tokenIds; // All the same plus _tokenId require( dstRepOld.length + 1 <= MAX_DELEGATES, "dstRep would have too many tokenIds" ); for (uint i = 0; i < dstRepOld.length; i++) { uint tId = dstRepOld[i]; dstRepNew.push(tId); } dstRepNew.push(_tokenId); numCheckpoints[dstRep] = dstRepNum + 1; } } } function _findWhatCheckpointToWrite(address account) internal view returns (uint32) { uint _timestamp = block.timestamp; uint32 _nCheckPoints = numCheckpoints[account]; if ( _nCheckPoints > 0 && checkpoints[account][_nCheckPoints - 1].timestamp == _timestamp ) { return _nCheckPoints - 1; } else { return _nCheckPoints; } } function _moveAllDelegates( address owner, address srcRep, address dstRep ) internal { // You can only redelegate what you own if (srcRep != dstRep) { if (srcRep != address(0)) { uint32 srcRepNum = numCheckpoints[srcRep]; uint[] storage srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].tokenIds : checkpoints[srcRep][0].tokenIds; uint32 nextSrcRepNum = _findWhatCheckpointToWrite(srcRep); uint[] storage srcRepNew = checkpoints[srcRep][ nextSrcRepNum ].tokenIds; // All the same except what owner owns for (uint i = 0; i < srcRepOld.length; i++) { uint tId = srcRepOld[i]; if (idToOwner[tId] != owner) { srcRepNew.push(tId); } } numCheckpoints[srcRep] = srcRepNum + 1; } if (dstRep != address(0)) { uint32 dstRepNum = numCheckpoints[dstRep]; uint[] storage dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].tokenIds : checkpoints[dstRep][0].tokenIds; uint32 nextDstRepNum = _findWhatCheckpointToWrite(dstRep); uint[] storage dstRepNew = checkpoints[dstRep][ nextDstRepNum ].tokenIds; uint ownerTokenCount = ownerToNFTokenCount[owner]; require( dstRepOld.length + ownerTokenCount <= MAX_DELEGATES, "dstRep would have too many tokenIds" ); // All the same for (uint i = 0; i < dstRepOld.length; i++) { uint tId = dstRepOld[i]; dstRepNew.push(tId); } // Plus all that's owned for (uint i = 0; i < ownerTokenCount; i++) { uint tId = ownerToNFTokenIdList[owner][i]; dstRepNew.push(tId); } numCheckpoints[dstRep] = dstRepNum + 1; } } } function _delegate(address delegator, address delegatee) internal { /// @notice differs from `_delegate()` in `Comp.sol` to use `delegates` override method to simulate auto-delegation address currentDelegate = delegates(delegator); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveAllDelegates(delegator, currentDelegate, delegatee); } /** * @notice Delegate votes from `msg.sender` to `delegatee` * @param delegatee The address to delegate votes to */ function delegate(address delegatee) public { if (delegatee == address(0)) delegatee = msg.sender; return _delegate(msg.sender, delegatee); } function delegateBySig( address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s ) public { bytes32 domainSeparator = keccak256( abi.encode( DOMAIN_TYPEHASH, keccak256(bytes(name)), keccak256(bytes(version)), block.chainid, address(this) ) ); bytes32 structHash = keccak256( abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry) ); bytes32 digest = keccak256( abi.encodePacked("\x19\x01", domainSeparator, structHash) ); address signatory = ecrecover(digest, v, r, s); require( signatory != address(0), "VotingEscrow::delegateBySig: invalid signature" ); require( nonce == nonces[signatory]++, "VotingEscrow::delegateBySig: invalid nonce" ); require( block.timestamp <= expiry, "VotingEscrow::delegateBySig: signature expired" ); return _delegate(signatory, delegatee); } }
[{"inputs":[{"internalType":"address","name":"token_addr","type":"address"},{"internalType":"address","name":"art_proxy","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"locktime","type":"uint256"},{"indexed":false,"internalType":"enum VotingEscrow.DepositType","name":"deposit_type","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"prevSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"Supply","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DELEGATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_DELEGATES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"abstain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_approved","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"artProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"attach","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"attachments","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"balanceOfAtNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"balanceOfNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_t","type":"uint256"}],"name":"balanceOfNFTAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"block_number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint32","name":"","type":"uint32"}],"name":"checkpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_lock_duration","type":"uint256"}],"name":"create_lock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_lock_duration","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"create_lock_for","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"deposit_for","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"detach","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPastVotesIndex","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"get_last_user_slope","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"increase_amount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_lock_duration","type":"uint256"}],"name":"increase_unlock_time","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"isApprovedOrOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"locked","outputs":[{"internalType":"int128","name":"amount","type":"int128"},{"internalType":"uint256","name":"end","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"locked__end","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"merge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownership_change","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"point_history","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"},{"internalType":"uint256","name":"blk","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proxy","type":"address"}],"name":"setArtProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_team","type":"address"}],"name":"setTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_voter","type":"address"}],"name":"setVoter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"slope_changes","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"team","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_tokenIndex","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"t","type":"uint256"}],"name":"totalSupplyAtT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"user_point_epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"user_point_history","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"},{"internalType":"uint256","name":"blk","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"user_point_history__ts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"voted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"voting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040526006805460ff191660011790553480156200001e57600080fd5b5060405162004a1c38038062004a1c8339810160408190526200004191620001b8565b6001600160a01b0382811660805260008054336001600160a01b031991821681178355600180548316909117815560028054909216938516939093179055437f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92f0155427f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92f005560046020527f9fe05126d2d9ecf60592e254dead906a4b2e492f36cca727682c38e9008c6ac1805460ff1990811684179091557f4267c0a6fd96b7a87f183ee8744f24d011423cd0e0142b3f563f183d8d9a456b8054821684179055635b5e139f60e01b82527e24030bcf4927897dffe721c2d8dda4bfd8910861687c42b03a463b43b04147805490911690921790915560055460405190913091600080516020620049fc833981519152908290a46005546040516000903090600080516020620049fc833981519152908390a45050620001f0565b80516001600160a01b0381168114620001b357600080fd5b919050565b60008060408385031215620001cc57600080fd5b620001d7836200019b565b9150620001e7602084016200019b565b90509250929050565b6080516147e26200021a60003960008181610b220152818161101801526133b501526147e26000f3fe608060405234801561001057600080fd5b50600436106104075760003560e01c80637116c60c11610220578063c1f0fb9f11610130578063e7a324dc116100b8578063f1127ed811610087578063f1127ed814610abc578063f8a0576314610ae7578063fbd3a29d14610b0a578063fc0c546a14610b1d578063fd4a77f114610b4457600080fd5b8063e7a324dc14610a33578063e7e242d414610a5a578063e985e9c514610a6d578063ee99fe2814610aa957600080fd5b8063d1c2babb116100ff578063d1c2babb1461099c578063d1febfb9146109af578063d4e54c3b146109ed578063e0514aba14610a00578063e441135c14610a1357600080fd5b8063c1f0fb9f1461095b578063c2c4c5c11461096e578063c3cda52014610976578063c87b56dd1461098957600080fd5b806395d89b41116101b3578063a183af5211610182578063a183af52146108c7578063a22cb465146108da578063a4d855df146108ed578063b45a3c0e14610900578063b88d4fde1461094857600080fd5b806395d89b4114610465578063981b24d01461088e578063986b7d8a146108a15780639ab24eb0146108b457600080fd5b80638c2c9baf116101ef5780638c2c9baf1461083c5780638e539e8c1461084f5780638fbb38ff14610862578063900cf0cf1461088557600080fd5b80637116c60c146107d357806371197484146107e65780637ecebe001461080957806385f2aef21461082957600080fd5b8063313ce5671161031b5780635594a045116102ae5780636352211e1161027d5780636352211e1461073e57806365fc3873146107675780636f5488371461077a5780636fcfff451461079a57806370a08231146107c057600080fd5b80635594a045146106fc578063587cde1e1461070f5780635c19a95c146107225780635f5b0c321461073557600080fd5b8063461f711c116102ea578063461f711c1461068c57806346c96aac146106b25780634bc2a657146106c557806354fd4d50146106d857600080fd5b8063313ce567146106395780633a46b1a81461065357806342842e0e14610666578063430c20811461067957600080fd5b80631376f3da1161039e57806323b872dd1161036d57806323b872dd146105c457806325a58b56146105d75780632e1a7d4d146105dd5780632e720f7d146105f05780632f745c591461060357600080fd5b80631376f3da1461054757806318160ddd146105825780631c984bc31461058a57806320606b701461059d57600080fd5b8063081812fc116103da578063081812fc146104be578063095cf5c6146104ff578063095ea7b3146105145780630d6a20331461052757600080fd5b806301ffc9a71461040c578063047fc9aa1461044e57806306fdde03146104655780630758c7d814610496575b600080fd5b61043961041a366004613f24565b6001600160e01b03191660009081526004602052604090205460ff1690565b60405190151581526020015b60405180910390f35b61045760135481565b604051908152602001610445565b610489604051806040016040528060058152602001641d9953919560da1b81525081565b6040516104459190613f99565b6104a96104a4366004613fc8565b610b57565b60405163ffffffff9091168152602001610445565b6104e76104cc366004613ff2565b6000908152600960205260409020546001600160a01b031690565b6040516001600160a01b039091168152602001610445565b61051261050d36600461400b565b610cca565b005b610512610522366004613fc8565b610d03565b610457610535366004613ff2565b60146020526000908152604090205481565b61055a610555366004614026565b610deb565b60408051600f95860b81529390940b6020840152928201526060810191909152608001610445565b610457610e32565b610457610598366004614026565b610e42565b6104577f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6105126105d2366004614048565b610e74565b43610457565b6105126105eb366004613ff2565b610e85565b6105126105fe36600461400b565b61113b565b610457610611366004613fc8565b6001600160a01b03919091166000908152600c60209081526040808320938352929052205490565b610641601281565b60405160ff9091168152602001610445565b610457610661366004613fc8565b611174565b610512610674366004614048565b611213565b610439610687366004613fc8565b61122e565b61069f61069a366004613ff2565b611241565b604051600f9190910b8152602001610445565b6000546104e7906001600160a01b031681565b6105126106d336600461400b565b611284565b610489604051806040016040528060058152602001640312e302e360dc1b81525081565b6002546104e7906001600160a01b031681565b6104e761071d36600461400b565b6112bd565b61051261073036600461400b565b6112ed565b61045761040081565b6104e761074c366004613ff2565b6000908152600760205260409020546001600160a01b031690565b610457610775366004614026565b61130b565b610457610788366004613ff2565b600b6020526000908152604090205481565b6104a96107a836600461400b565b60186020526000908152604090205463ffffffff1681565b6104576107ce36600461400b565b61134d565b6104576107e1366004613ff2565b61136b565b61069f6107f4366004613ff2565b601260205260009081526040902054600f0b81565b61045761081736600461400b565b60196020526000908152604090205481565b6001546104e7906001600160a01b031681565b61045761084a366004614026565b6113cb565b61045761085d366004613ff2565b6113d7565b610439610870366004613ff2565b60156020526000908152604090205460ff1681565b61045760115481565b61045761089c366004613ff2565b6113e2565b6105126108af366004613ff2565b611584565b6104576108c236600461400b565b6115c8565b6105126108d5366004614026565b61169b565b6105126108e8366004614092565b61179a565b6105126108fb366004614026565b61181e565b61092e61090e366004613ff2565b60106020526000908152604090208054600190910154600f9190910b9082565b60408051600f9390930b8352602083019190915201610445565b610512610956366004614138565b611a03565b610512610969366004613ff2565b611ba2565b610512611bd1565b6105126109843660046141e3565b611c11565b610489610997366004613ff2565b611f51565b6105126109aa366004614026565b61207d565b61055a6109bd366004613ff2565b600360205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b6104576109fb366004614243565b6121e2565b610457610a0e366004614026565b612225565b610457610a21366004613ff2565b600e6020526000908152604090205481565b6104577fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b610457610a68366004613ff2565b612231565b610439610a7b366004614278565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b610512610ab7366004614026565b612259565b610457610aca3660046142ab565b601760209081526000928352604080842090915290825290205481565b610457610af5366004613ff2565b60009081526010602052604090206001015490565b610512610b18366004613ff2565b61232d565b6104e77f000000000000000000000000000000000000000000000000000000000000000081565b610512610b52366004613ff2565b61235e565b6001600160a01b03821660009081526018602052604081205463ffffffff16808203610b87576000915050610cc4565b6001600160a01b03841660009081526017602052604081208491610bac6001856142f6565b63ffffffff16815260208101919091526040016000205411610bdb57610bd36001826142f6565b915050610cc4565b6001600160a01b0384166000908152601760209081526040808320838052909152902054831015610c10576000915050610cc4565b600080610c1e6001846142f6565b90505b8163ffffffff168163ffffffff161115610cbf5760006002610c4384846142f6565b610c4d9190614331565b610c5790836142f6565b6001600160a01b038816600090815260176020908152604080832063ffffffff851684529091529020805491925090879003610c9957509350610cc492505050565b8054871115610caa57819350610cb8565b610cb56001836142f6565b92505b5050610c21565b509150505b92915050565b6001546001600160a01b03163314610ce157600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600760205260409020546001600160a01b031680610d2557600080fd5b806001600160a01b0316836001600160a01b031603610d4357600080fd5b6000828152600760209081526040808320546001600160a01b038581168552600a845282852033808752945291909320549216149060ff168180610d845750805b610d8d57600080fd5b60008481526009602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a45050505050565b600f60205281600052604060002081633b9aca008110610e0a57600080fd5b6003020180546001820154600290920154600f82810b9550600160801b90920490910b925084565b6000610e3d4261136b565b905090565b6000828152600f6020526040812082633b9aca008110610e6457610e64614354565b6003020160010154905092915050565b610e8083838333612390565b505050565b60065460ff16600114610e9757600080fd5b6006805460ff19166002179055610eae3382612471565b610eba57610eba61436a565b600081815260146020526040902054158015610ee5575060008181526015602052604090205460ff16155b610f0a5760405162461bcd60e51b8152600401610f0190614380565b60405180910390fd5b60008181526010602090815260409182902082518084019093528054600f0b835260010154908201819052421015610f7d5760405162461bcd60e51b8152602060048201526016602482015275546865206c6f636b206469646e27742065787069726560501b6044820152606401610f01565b8051604080518082018252600080825260208083018281528783526010909152929020905181546001600160801b0319166001600160801b039091161781559051600190910155601354600f9190910b90610fd882826143a2565b6013556040805180820190915260008082526020820152610ffc90859085906124d7565b60405163a9059cbb60e01b8152336004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015611069573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108d91906143b9565b6110995761109961436a565b6110a284612af3565b60408051858152602081018490524281830152905133917f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94919081900360600190a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c8161111084826143a2565b6040805192835260208301919091520160405180910390a150506006805460ff191660011790555050565b6001546001600160a01b0316331461115257600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000806111818484610b57565b6001600160a01b038516600090815260176020908152604080832063ffffffff851684529091528120919250600190910190805b82548110156112095760008382815481106111d2576111d2614354565b906000526020600020015490506111e98188612bc6565b6111f390846143d6565b9250508080611201906143ee565b9150506111b5565b5095945050505050565b610e8083838360405180602001604052806000815250611a03565b600061123a8383612471565b9392505050565b6000818152600e6020908152604080832054600f909252822081633b9aca00811061126e5761126e614354565b6003020154600160801b9004600f0b9392505050565b6000546001600160a01b0316331461129b57600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0380821660009081526016602052604081205490911680156112e6578061123a565b5090919050565b6001600160a01b0381166112fe5750335b6113083382612c9a565b50565b60065460009060ff1660011461132057600080fd5b6006805460ff19166002179055611338838333612d0d565b90506006805460ff1916600117905592915050565b6001600160a01b038116600090815260086020526040812054610cc4565b601154600081815260036020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529091906113c38185612e64565b949350505050565b600061123a8383612f65565b6000610cc48261136b565b6000438211156113f4576113f461436a565b6011546000611403848361323e565b600081815260036020908152604080832081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060820152919250838310156115125760006003816114668660016143d6565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608083018290528501519192501461150c57826060015181606001516114d291906143a2565b836040015182604001516114e691906143a2565b60608501516114f5908a6143a2565b6114ff9190614407565b6115099190614426565b91505b50611561565b4382606001511461156157606082015161152c90436143a2565b604083015161153b90426143a2565b606084015161154a90896143a2565b6115549190614407565b61155e9190614426565b90505b61157a8282846040015161157591906143d6565b612e64565b9695505050505050565b6000546001600160a01b0316331461159b57600080fd5b6000818152601460205260409020546115b6906001906143a2565b60009182526014602052604090912055565b6001600160a01b03811660009081526018602052604081205463ffffffff168082036115f75750600092915050565b6001600160a01b03831660009081526017602052604081208161161b6001856142f6565b63ffffffff1663ffffffff16815260200190815260200160002060010190506000805b825481101561169257600083828154811061165b5761165b614354565b906000526020600020015490506116728142612bc6565b61167c90846143d6565b925050808061168a906143ee565b91505061163e565b50949350505050565b60065460ff166001146116ad57600080fd5b6006805460ff191660021790556116c43383612471565b6116d0576116d061436a565b60008281526010602090815260409182902082518084019093528054600f0b83526001015490820152816117065761170661436a565b60008160000151600f0b136117565760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b6044820152606401610f01565b428160200151116117795760405162461bcd60e51b8152600401610f019061443a565b611788838360008460026132c4565b50506006805460ff1916600117905550565b336001600160a01b038316036117b2576117b261436a565b336000818152600a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60065460ff1660011461183057600080fd5b6006805460ff191660021790556118473383612471565b6118535761185361436a565b600082815260106020908152604080832081518083019092528054600f0b825260010154918101919091529062093a808061188e85426143d6565b6118989190614426565b6118a29190614407565b9050428260200151116118e65760405162461bcd60e51b815260206004820152600c60248201526b131bd8dac8195e1c1a5c995960a21b6044820152606401610f01565b60008260000151600f0b136119315760405162461bcd60e51b8152602060048201526011602482015270139bdd1a1a5b99c81a5cc81b1bd8dad959607a1b6044820152606401610f01565b816020015181116119845760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e006044820152606401610f01565b611992630784ce00426143d6565b8111156119e15760405162461bcd60e51b815260206004820152601e60248201527f566f74696e67206c6f636b2063616e2062652034207965617273206d617800006044820152606401610f01565b6119f0846000838560036132c4565b50506006805460ff191660011790555050565b611a0f84848433612390565b823b15611b9c57604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290611a4890339088908790879060040161447e565b6020604051808303816000875af1925050508015611a83575060408051601f3d908101601f19168201909252611a80918101906144b1565b60015b611b2b573d808015611ab1576040519150601f19603f3d011682016040523d82523d6000602084013e611ab6565b606091505b508051600003611b235760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610f01565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14611b9a5760405162461bcd60e51b815260206004820152602660248201527f4552433732313a2045524337323152656365697665722072656a656374656420604482015265746f6b656e7360d01b6064820152608401610f01565b505b50505050565b6000546001600160a01b03163314611bb957600080fd5b6000908152601560205260409020805460ff19169055565b611c0f600060405180604001604052806000600f0b8152602001600081525060405180604001604052806000600f0b815260200160008152506124d7565b565b6040805180820182526005808252641d9953919560da1b60209283015282518084018452908152640312e302e360dc1b9082015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527fc792e9874e7b42c234d1e8448cec020a0f065019c8cd6f7ccdb65b8c110157e9818401527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c60608201524660808201523060a0808301919091528351808303909101815260c0820184528051908301207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60e08301526001600160a01b038a1661010083015261012082018990526101408083018990528451808403909101815261016083019094528351939092019290922061190160f01b61018084015261018283018290526101a2830181905290916000906101c20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015611dd0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611e4a5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e7660448201526d616c6964207369676e617475726560901b6064820152608401610f01565b6001600160a01b0381166000908152601960205260408120805491611e6e836143ee565b919050558914611ed35760405162461bcd60e51b815260206004820152602a60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e76604482015269616c6964206e6f6e636560b01b6064820152608401610f01565b87421115611f3a5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a2073696760448201526d1b985d1d5c9948195e1c1a5c995960921b6064820152608401610f01565b611f44818b612c9a565b505050505b505050505050565b6000818152600760205260409020546060906001600160a01b0316611fb85760405162461bcd60e51b815260206004820152601b60248201527f517565727920666f72206e6f6e6578697374656e7420746f6b656e00000000006044820152606401610f01565b60008281526010602090815260409182902082518084019093528054600f0b835260010154908201526002546001600160a01b031663dd9ec14984611ffd8142612bc6565b6020850151855160405160e086901b6001600160e01b0319168152600481019490945260248401929092526044830152600f0b6064820152608401600060405180830381865afa158015612055573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261123a91908101906144ce565b6000828152601460205260409020541580156120a8575060008281526015602052604090205460ff16155b6120c45760405162461bcd60e51b8152600401610f0190614380565b8082036120d057600080fd5b6120da3383612471565b6120e357600080fd5b6120ed3382612471565b6120f657600080fd5b6000828152601060208181526040808420815180830183528154600f90810b825260019283015482860190815288885295855283872084518086019095528054820b855290920154938301849052805194519095929490910b921115612160578260200151612166565b83602001515b604080518082018252600080825260208083018281528b835260108252848320935184546001600160801b0319166001600160801b03909116178455516001909301929092558251808401909352808352908201529091506121cb90879086906124d7565b6121d486612af3565b611f498583838660046132c4565b60065460009060ff166001146121f757600080fd5b6006805460ff1916600217905561220f848484612d0d565b90506006805460ff191660011790559392505050565b600061123a8383612bc6565b6000818152600b602052604081205443900361224f57506000919050565b610cc48242612bc6565b60065460ff1660011461226b57600080fd5b6006805460ff1916600217905560008281526010602090815260409182902082518084019093528054600f0b83526001015490820152816122ab57600080fd5b60008160000151600f0b136122fb5760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b6044820152606401610f01565b4281602001511161231e5760405162461bcd60e51b8152600401610f019061443a565b611788838360008460006132c4565b6000546001600160a01b0316331461234457600080fd5b6000818152601460205260409020546115b69060016143d6565b6000546001600160a01b0316331461237557600080fd5b6000908152601560205260409020805460ff19166001179055565b6000828152601460205260409020541580156123bb575060008281526015602052604090205460ff16155b6123d75760405162461bcd60e51b8152600401610f0190614380565b6123e18183612471565b6123ea57600080fd5b6123f484836134c9565b6123fe8483613530565b61241961240a856112bd565b612413856112bd565b846135b1565b6124238383613913565b6000828152600b60205260408082204390555183916001600160a01b0380871692908816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a450505050565b60008181526007602090815260408083205460098352818420546001600160a01b03918216808652600a855283862088841680885295529285205492938085149392909116149060ff1682806124c45750815b806124cc5750805b979650505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091526011546000908190871561264257428760200151118015612547575060008760000151600f0b135b1561258c57865161255d90630784ce009061453c565b600f0b6020808701919091528701516125779042906143a2565b8560200151612586919061457a565b600f0b85525b4286602001511180156125a6575060008660000151600f0b135b156125eb5785516125bc90630784ce009061453c565b600f0b6020808601919091528601516125d69042906143a2565b84602001516125e5919061457a565b600f0b84525b602080880151600090815260128252604090205490870151600f9190910b93501561264257866020015186602001510361262757829150612642565b602080870151600090815260129091526040902054600f0b91505b6040805160808101825260008082526020820152429181019190915243606082015281156126b7575060008181526003602090815260409182902082516080810184528154600f81810b8352600160801b909104900b9281019290925260018101549282019290925260029091015460608201525b6040810151816000428310156127045760408401516126d690426143a2565b60608501516126e590436143a2565b6126f790670de0b6b3a7640000614407565b6127019190614426565b90505b600062093a806127148186614426565b61271e9190614407565b905060005b60ff8110156128985761273962093a80836143d6565b915060004283111561274d57429250612761565b50600082815260126020526040902054600f0b5b61276b86846143a2565b876020015161277a919061457a565b8751889061278990839061460f565b600f0b9052506020870180518291906127a390839061465f565b600f90810b90915288516000910b121590506127be57600087525b60008760200151600f0b12156127d657600060208801525b60408088018490528501519295508592670de0b6b3a7640000906127fa90856143a2565b6128049086614407565b61280e9190614426565b856060015161281d91906143d6565b606088015261282d6001896143d6565b97504283036128425750436060870152612898565b6000888152600360209081526040918290208951918a01516001600160801b03908116600160801b029216919091178155908801516001820155606088015160029091015550612891816143ee565b9050612723565b505060118590558b1561292357886020015188602001516128b9919061460f565b846020018181516128ca919061465f565b600f0b905250885188516128de919061460f565b845185906128ed90839061465f565b600f90810b90915260208601516000910b1215905061290e57600060208501525b60008460000151600f0b121561292357600084525b6000858152600360209081526040918290208651918701516001600160801b03908116600160801b02921691909117815590850151600182015560608501516002909101558b15612ae557428b6020015111156129da576020890151612989908861465f565b96508a602001518a60200151036129ac5760208801516129a9908861460f565b96505b60208b810151600090815260129091526040902080546001600160801b0319166001600160801b0389161790555b428a602001511115612a35578a602001518a602001511115612a35576020880151612a05908761460f565b60208b810151600090815260129091526040902080546001600160801b0319166001600160801b03831617905595505b60008c8152600e6020526040812054612a4f9060016143d6565b905080600e60008f815260200190815260200160002081905550428960400181815250504389606001818152505088600f60008f815260200190815260200160002082633b9aca008110612aa557612aa5614354565b825160208401516001600160801b03908116600160801b029116176003919091029190910190815560408201516001820155606090910151600290910155505b505050505050505050505050565b612afd3382612471565b612b495760405162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665646044820152606401610f01565b6000818152600760205260408120546001600160a01b031690612b6c9083610d03565b612b80612b78826112bd565b6000846135b1565b612b8a3383613530565b60405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000828152600e6020526040812054808203612be6576000915050610cc4565b6000848152600f6020526040812082633b9aca008110612c0857612c08614354565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b602083015260018101549282018390526002015460608201529150612c5490856146ae565b8160200151612c63919061457a565b81518290612c7290839061460f565b600f90810b90915282516000910b12159050612c8d57600081525b51600f0b9150610cc49050565b6000612ca5836112bd565b6001600160a01b0384811660008181526016602052604080822080546001600160a01b031916888616908117909155905194955093928516927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4610e808382846139a9565b60008062093a8080612d1f86426143d6565b612d299190614426565b612d339190614407565b905060008511612d4257600080fd5b428111612da05760405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e207468652060448201526566757475726560d01b6064820152608401610f01565b612dae630784ce00426143d6565b811115612dfd5760405162461bcd60e51b815260206004820152601e60248201527f566f74696e67206c6f636b2063616e2062652034207965617273206d617800006044820152606401610f01565b600560008154612e0c906143ee565b90915550600554612e1d8482613d65565b5060008181526010602090815260409182902082518084019093528054600f0b835260019081015491830191909152612e5b918391899186916132c4565b95945050505050565b600080839050600062093a80808360400151612e809190614426565b612e8a9190614407565b905060005b60ff811015612f3d57612ea562093a80836143d6565b9150600085831115612eb957859250612ecd565b50600082815260126020526040902054600f0b5b6040840151612edc90846143a2565b8460200151612eeb919061457a565b84518590612efa90839061460f565b600f0b905250858303612f0d5750612f3d565b8084602001818151612f1f919061465f565b600f0b9052505060408301829052612f36816143ee565b9050612e8f565b5060008260000151600f0b1215612f5357600082525b50516001600160801b03169392505050565b600043821115612f7757612f7761436a565b6000838152600e6020526040812054815b608081101561301757818310156130175760006002612fa784866143d6565b612fb29060016143d6565b612fbc9190614426565b6000888152600f60205260409020909150869082633b9aca008110612fe357612fe3614354565b600302016002015411612ff857809350613006565b6130036001826143a2565b92505b50613010816143ee565b9050612f88565b506000858152600f6020526040812083633b9aca00811061303a5761303a614354565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b60208301526001810154928201929092526002909101546060820152601154909150600061308f878361323e565b600081815260036020908152604080832081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060820152919250808484101561316e5760006003816130f38760016143d6565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905286015191925061315091906143a2565b92508360400151816040015161316691906143a2565b915050613192565b606083015161317d90436143a2565b915082604001514261318f91906143a2565b90505b604083015182156131cf578284606001518c6131ae91906143a2565b6131b89084614407565b6131c29190614426565b6131cc90826143d6565b90505b60408701516131de90826143a2565b87602001516131ed919061457a565b875188906131fc90839061460f565b600f90810b90915288516000910b12905061322c57505093516001600160801b03169650610cc495505050505050565b60009950505050505050505050610cc4565b60008082815b60808110156132ba57818310156132ba576000600261326384866143d6565b61326e9060016143d6565b6132789190614426565b600081815260036020526040902060020154909150871061329b578093506132a9565b6132a66001826143a2565b92505b506132b3816143ee565b9050613244565b5090949350505050565b60135482906132d386826143d6565b6013556040805180820190915260008082526020820152825160208085015190830152600f0b815282518790849061330c90839061465f565b600f0b905250851561332057602083018690525b6000888152601060209081526040909120845181546001600160801b0319166001600160801b03909116178155908401516001909101556133628882856124d7565b33871580159061338457506004856004811115613381576133816146ed565b14155b1561342e576040516323b872dd60e01b81526001600160a01b038281166004830152306024830152604482018a90527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906064016020604051808303816000875af11580156133fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342291906143b9565b61342e5761342e61436a565b8360200151816001600160a01b03167fff04ccafc360e16b67d682d17bd9503c4c6b9a131f6be6325762dc9ffc7de6248b8b89426040516134729493929190614703565b60405180910390a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c836134a68a826143d6565b6040805192835260208301919091520160405180910390a1505050505050505050565b6000818152600760205260409020546001600160a01b038381169116146134f2576134f261436a565b6000818152600960205260409020546001600160a01b03161561352c57600081815260096020526040902080546001600160a01b03191690555b5050565b6000818152600760205260409020546001600160a01b038381169116146135595761355961436a565b600081815260076020526040902080546001600160a01b031916905561357f8282613dd6565b6001600160a01b03821660009081526008602052604081208054600192906135a89084906143a2565b90915550505050565b816001600160a01b0316836001600160a01b0316141580156135d35750600081115b15610e80576001600160a01b03831615613754576001600160a01b03831660009081526018602052604081205463ffffffff169081613637576001600160a01b03851660009081526017602090815260408083208380529091529020600101613679565b6001600160a01b03851660009081526017602052604081209061365b6001856142f6565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061368686613e95565b6001600160a01b038716600090815260176020908152604080832063ffffffff8516845290915281209192506001909101905b83548110156137135760008482815481106136d6576136d6614354565b90600052602060002001549050868114613700578254600181018455600084815260209020018190555b508061370b816143ee565b9150506136b9565b5061371f846001614741565b6001600160a01b0388166000908152601860205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03821615610e80576001600160a01b03821660009081526018602052604081205463ffffffff1690816137b3576001600160a01b038416600090815260176020908152604080832083805290915290206001016137f5565b6001600160a01b0384166000908152601760205260408120906137d76001856142f6565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061380285613e95565b6001600160a01b038616600090815260176020908152604080832063ffffffff85168452909152902083549192506001908101916104009161384491906143d6565b11156138625760405162461bcd60e51b8152600401610f0190614769565b60005b83548110156138b457600084828154811061388257613882614354565b6000918252602080832090910154855460018101875586845291909220015550806138ac816143ee565b915050613865565b508054600181810183556000838152602090209091018690556138d8908590614741565b6001600160a01b0387166000908152601860205260409020805463ffffffff9290921663ffffffff1990921691909117905550505050505050565b6000818152600760205260409020546001600160a01b0316156139385761393861436a565b600081815260076020908152604080832080546001600160a01b0319166001600160a01b03871690811790915580845260088084528285208054600c86528487208188528652848720889055878752600d8652938620939093559084529091528054600192906135a89084906143d6565b806001600160a01b0316826001600160a01b031614610e80576001600160a01b03821615613b5c576001600160a01b03821660009081526018602052604081205463ffffffff169081613a21576001600160a01b03841660009081526017602090815260408083208380529091529020600101613a63565b6001600160a01b038416600090815260176020526040812090613a456001856142f6565b63ffffffff1663ffffffff1681526020019081526020016000206001015b90506000613a7085613e95565b6001600160a01b038616600090815260176020908152604080832063ffffffff8516845290915281209192506001909101905b8354811015613b1b576000848281548110613ac057613ac0614354565b600091825260208083209091015480835260079091526040909120549091506001600160a01b03908116908a1614613b08578254600181018455600084815260209020018190555b5080613b13816143ee565b915050613aa3565b50613b27846001614741565b6001600160a01b0387166000908152601860205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03811615610e80576001600160a01b03811660009081526018602052604081205463ffffffff169081613bbb576001600160a01b03831660009081526017602090815260408083208380529091529020600101613bfd565b6001600160a01b038316600090815260176020526040812090613bdf6001856142f6565b63ffffffff1663ffffffff1681526020019081526020016000206001015b90506000613c0a84613e95565b6001600160a01b03808616600090815260176020908152604080832063ffffffff861684528252808320938b1683526008909152902054845492935060019091019161040090613c5b9083906143d6565b1115613c795760405162461bcd60e51b8152600401610f0190614769565b60005b8454811015613ccb576000858281548110613c9957613c99614354565b600091825260208083209091015486546001810188558784529190922001555080613cc3816143ee565b915050613c7c565b5060005b81811015613d1d576001600160a01b0389166000908152600c602090815260408083208484528252822054855460018101875586845291909220015580613d15816143ee565b915050613ccf565b50613d29856001614741565b6001600160a01b0387166000908152601860205260409020805463ffffffff9290921663ffffffff199092169190911790555050505050505050565b60006001600160a01b038316613d7d57613d7d61436a565b613d8b6000612413856112bd565b613d958383613913565b60405182906001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450600192915050565b6001600160a01b038216600090815260086020526040812054613dfb906001906143a2565b6000838152600d6020526040902054909150808203613e4a576001600160a01b0384166000908152600c602090815260408083208584528252808320839055858352600d909152812055611b9c565b6001600160a01b03939093166000908152600c6020908152604080832093835292815282822080548684528484208190558352600d9091528282209490945592839055908252812055565b6001600160a01b038116600090815260186020526040812054429063ffffffff168015801590613efe57506001600160a01b03841660009081526017602052604081208391613ee56001856142f6565b63ffffffff168152602081019190915260400160002054145b1561123a576113c36001826142f6565b6001600160e01b03198116811461130857600080fd5b600060208284031215613f3657600080fd5b813561123a81613f0e565b60005b83811015613f5c578181015183820152602001613f44565b83811115611b9c5750506000910152565b60008151808452613f85816020860160208601613f41565b601f01601f19169290920160200192915050565b60208152600061123a6020830184613f6d565b80356001600160a01b0381168114613fc357600080fd5b919050565b60008060408385031215613fdb57600080fd5b613fe483613fac565b946020939093013593505050565b60006020828403121561400457600080fd5b5035919050565b60006020828403121561401d57600080fd5b61123a82613fac565b6000806040838503121561403957600080fd5b50508035926020909101359150565b60008060006060848603121561405d57600080fd5b61406684613fac565b925061407460208501613fac565b9150604084013590509250925092565b801515811461130857600080fd5b600080604083850312156140a557600080fd5b6140ae83613fac565b915060208301356140be81614084565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614108576141086140c9565b604052919050565b600067ffffffffffffffff82111561412a5761412a6140c9565b50601f01601f191660200190565b6000806000806080858703121561414e57600080fd5b61415785613fac565b935061416560208601613fac565b925060408501359150606085013567ffffffffffffffff81111561418857600080fd5b8501601f8101871361419957600080fd5b80356141ac6141a782614110565b6140df565b8181528860208385010111156141c157600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060008060008060c087890312156141fc57600080fd5b61420587613fac565b95506020870135945060408701359350606087013560ff8116811461422957600080fd5b9598949750929560808101359460a0909101359350915050565b60008060006060848603121561425857600080fd5b833592506020840135915061426f60408501613fac565b90509250925092565b6000806040838503121561428b57600080fd5b61429483613fac565b91506142a260208401613fac565b90509250929050565b600080604083850312156142be57600080fd5b6142c783613fac565b9150602083013563ffffffff811681146140be57600080fd5b634e487b7160e01b600052601160045260246000fd5b600063ffffffff83811690831681811015614313576143136142e0565b039392505050565b634e487b7160e01b600052601260045260246000fd5b600063ffffffff808416806143485761434861431b565b92169190910492915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052600160045260246000fd5b602080825260089082015267185d1d1858da195960c21b604082015260600190565b6000828210156143b4576143b46142e0565b500390565b6000602082840312156143cb57600080fd5b815161123a81614084565b600082198211156143e9576143e96142e0565b500190565b600060018201614400576144006142e0565b5060010190565b6000816000190483118215151615614421576144216142e0565b500290565b6000826144355761443561431b565b500490565b60208082526024908201527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686040820152636472617760e01b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061157a90830184613f6d565b6000602082840312156144c357600080fd5b815161123a81613f0e565b6000602082840312156144e057600080fd5b815167ffffffffffffffff8111156144f757600080fd5b8201601f8101841361450857600080fd5b80516145166141a782614110565b81815285602083850101111561452b57600080fd5b612e5b826020830160208601613f41565b600081600f0b83600f0b806145535761455361431b565b60016001607f1b0319821460001982141615614571576145716142e0565b90059392505050565b600081600f0b83600f0b60016001607f1b036000821360008413838304851182821616156145aa576145aa6142e0565b60016001607f1b031960008512828116878305871216156145cd576145cd6142e0565b600087129250858205871284841616156145e9576145e96142e0565b858505871281841616156145ff576145ff6142e0565b5050509290910295945050505050565b600081600f0b83600f0b600081128160016001607f1b03190183128115161561463a5761463a6142e0565b8160016001607f1b03018313811615614655576146556142e0565b5090039392505050565b600081600f0b83600f0b600082128260016001607f1b0303821381151615614689576146896142e0565b8260016001607f1b03190382128116156146a5576146a56142e0565b50019392505050565b60008083128015600160ff1b8501841216156146cc576146cc6142e0565b6001600160ff1b03840183138116156146e7576146e76142e0565b50500390565b634e487b7160e01b600052602160045260246000fd5b84815260208101849052608081016005841061472f57634e487b7160e01b600052602160045260246000fd5b60408201939093526060015292915050565b600063ffffffff808316818516808303821115614760576147606142e0565b01949350505050565b60208082526023908201527f64737452657020776f756c64206861766520746f6f206d616e7920746f6b656e60408201526249647360e81b60608201526080019056fea2646970667358221220a924c6b408183e88d44826bd2b4de73ab466a4dd207271d230454486985d359464736f6c634300080d0033ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000d83e12b3ad06914b4018f17ae47ae39f3584dfad00000000000000000000000021905102de17af6d4a4403258b7106a05f798bc9
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104075760003560e01c80637116c60c11610220578063c1f0fb9f11610130578063e7a324dc116100b8578063f1127ed811610087578063f1127ed814610abc578063f8a0576314610ae7578063fbd3a29d14610b0a578063fc0c546a14610b1d578063fd4a77f114610b4457600080fd5b8063e7a324dc14610a33578063e7e242d414610a5a578063e985e9c514610a6d578063ee99fe2814610aa957600080fd5b8063d1c2babb116100ff578063d1c2babb1461099c578063d1febfb9146109af578063d4e54c3b146109ed578063e0514aba14610a00578063e441135c14610a1357600080fd5b8063c1f0fb9f1461095b578063c2c4c5c11461096e578063c3cda52014610976578063c87b56dd1461098957600080fd5b806395d89b41116101b3578063a183af5211610182578063a183af52146108c7578063a22cb465146108da578063a4d855df146108ed578063b45a3c0e14610900578063b88d4fde1461094857600080fd5b806395d89b4114610465578063981b24d01461088e578063986b7d8a146108a15780639ab24eb0146108b457600080fd5b80638c2c9baf116101ef5780638c2c9baf1461083c5780638e539e8c1461084f5780638fbb38ff14610862578063900cf0cf1461088557600080fd5b80637116c60c146107d357806371197484146107e65780637ecebe001461080957806385f2aef21461082957600080fd5b8063313ce5671161031b5780635594a045116102ae5780636352211e1161027d5780636352211e1461073e57806365fc3873146107675780636f5488371461077a5780636fcfff451461079a57806370a08231146107c057600080fd5b80635594a045146106fc578063587cde1e1461070f5780635c19a95c146107225780635f5b0c321461073557600080fd5b8063461f711c116102ea578063461f711c1461068c57806346c96aac146106b25780634bc2a657146106c557806354fd4d50146106d857600080fd5b8063313ce567146106395780633a46b1a81461065357806342842e0e14610666578063430c20811461067957600080fd5b80631376f3da1161039e57806323b872dd1161036d57806323b872dd146105c457806325a58b56146105d75780632e1a7d4d146105dd5780632e720f7d146105f05780632f745c591461060357600080fd5b80631376f3da1461054757806318160ddd146105825780631c984bc31461058a57806320606b701461059d57600080fd5b8063081812fc116103da578063081812fc146104be578063095cf5c6146104ff578063095ea7b3146105145780630d6a20331461052757600080fd5b806301ffc9a71461040c578063047fc9aa1461044e57806306fdde03146104655780630758c7d814610496575b600080fd5b61043961041a366004613f24565b6001600160e01b03191660009081526004602052604090205460ff1690565b60405190151581526020015b60405180910390f35b61045760135481565b604051908152602001610445565b610489604051806040016040528060058152602001641d9953919560da1b81525081565b6040516104459190613f99565b6104a96104a4366004613fc8565b610b57565b60405163ffffffff9091168152602001610445565b6104e76104cc366004613ff2565b6000908152600960205260409020546001600160a01b031690565b6040516001600160a01b039091168152602001610445565b61051261050d36600461400b565b610cca565b005b610512610522366004613fc8565b610d03565b610457610535366004613ff2565b60146020526000908152604090205481565b61055a610555366004614026565b610deb565b60408051600f95860b81529390940b6020840152928201526060810191909152608001610445565b610457610e32565b610457610598366004614026565b610e42565b6104577f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6105126105d2366004614048565b610e74565b43610457565b6105126105eb366004613ff2565b610e85565b6105126105fe36600461400b565b61113b565b610457610611366004613fc8565b6001600160a01b03919091166000908152600c60209081526040808320938352929052205490565b610641601281565b60405160ff9091168152602001610445565b610457610661366004613fc8565b611174565b610512610674366004614048565b611213565b610439610687366004613fc8565b61122e565b61069f61069a366004613ff2565b611241565b604051600f9190910b8152602001610445565b6000546104e7906001600160a01b031681565b6105126106d336600461400b565b611284565b610489604051806040016040528060058152602001640312e302e360dc1b81525081565b6002546104e7906001600160a01b031681565b6104e761071d36600461400b565b6112bd565b61051261073036600461400b565b6112ed565b61045761040081565b6104e761074c366004613ff2565b6000908152600760205260409020546001600160a01b031690565b610457610775366004614026565b61130b565b610457610788366004613ff2565b600b6020526000908152604090205481565b6104a96107a836600461400b565b60186020526000908152604090205463ffffffff1681565b6104576107ce36600461400b565b61134d565b6104576107e1366004613ff2565b61136b565b61069f6107f4366004613ff2565b601260205260009081526040902054600f0b81565b61045761081736600461400b565b60196020526000908152604090205481565b6001546104e7906001600160a01b031681565b61045761084a366004614026565b6113cb565b61045761085d366004613ff2565b6113d7565b610439610870366004613ff2565b60156020526000908152604090205460ff1681565b61045760115481565b61045761089c366004613ff2565b6113e2565b6105126108af366004613ff2565b611584565b6104576108c236600461400b565b6115c8565b6105126108d5366004614026565b61169b565b6105126108e8366004614092565b61179a565b6105126108fb366004614026565b61181e565b61092e61090e366004613ff2565b60106020526000908152604090208054600190910154600f9190910b9082565b60408051600f9390930b8352602083019190915201610445565b610512610956366004614138565b611a03565b610512610969366004613ff2565b611ba2565b610512611bd1565b6105126109843660046141e3565b611c11565b610489610997366004613ff2565b611f51565b6105126109aa366004614026565b61207d565b61055a6109bd366004613ff2565b600360205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b6104576109fb366004614243565b6121e2565b610457610a0e366004614026565b612225565b610457610a21366004613ff2565b600e6020526000908152604090205481565b6104577fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b610457610a68366004613ff2565b612231565b610439610a7b366004614278565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b610512610ab7366004614026565b612259565b610457610aca3660046142ab565b601760209081526000928352604080842090915290825290205481565b610457610af5366004613ff2565b60009081526010602052604090206001015490565b610512610b18366004613ff2565b61232d565b6104e77f000000000000000000000000d83e12b3ad06914b4018f17ae47ae39f3584dfad81565b610512610b52366004613ff2565b61235e565b6001600160a01b03821660009081526018602052604081205463ffffffff16808203610b87576000915050610cc4565b6001600160a01b03841660009081526017602052604081208491610bac6001856142f6565b63ffffffff16815260208101919091526040016000205411610bdb57610bd36001826142f6565b915050610cc4565b6001600160a01b0384166000908152601760209081526040808320838052909152902054831015610c10576000915050610cc4565b600080610c1e6001846142f6565b90505b8163ffffffff168163ffffffff161115610cbf5760006002610c4384846142f6565b610c4d9190614331565b610c5790836142f6565b6001600160a01b038816600090815260176020908152604080832063ffffffff851684529091529020805491925090879003610c9957509350610cc492505050565b8054871115610caa57819350610cb8565b610cb56001836142f6565b92505b5050610c21565b509150505b92915050565b6001546001600160a01b03163314610ce157600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600760205260409020546001600160a01b031680610d2557600080fd5b806001600160a01b0316836001600160a01b031603610d4357600080fd5b6000828152600760209081526040808320546001600160a01b038581168552600a845282852033808752945291909320549216149060ff168180610d845750805b610d8d57600080fd5b60008481526009602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a45050505050565b600f60205281600052604060002081633b9aca008110610e0a57600080fd5b6003020180546001820154600290920154600f82810b9550600160801b90920490910b925084565b6000610e3d4261136b565b905090565b6000828152600f6020526040812082633b9aca008110610e6457610e64614354565b6003020160010154905092915050565b610e8083838333612390565b505050565b60065460ff16600114610e9757600080fd5b6006805460ff19166002179055610eae3382612471565b610eba57610eba61436a565b600081815260146020526040902054158015610ee5575060008181526015602052604090205460ff16155b610f0a5760405162461bcd60e51b8152600401610f0190614380565b60405180910390fd5b60008181526010602090815260409182902082518084019093528054600f0b835260010154908201819052421015610f7d5760405162461bcd60e51b8152602060048201526016602482015275546865206c6f636b206469646e27742065787069726560501b6044820152606401610f01565b8051604080518082018252600080825260208083018281528783526010909152929020905181546001600160801b0319166001600160801b039091161781559051600190910155601354600f9190910b90610fd882826143a2565b6013556040805180820190915260008082526020820152610ffc90859085906124d7565b60405163a9059cbb60e01b8152336004820152602481018390527f000000000000000000000000d83e12b3ad06914b4018f17ae47ae39f3584dfad6001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015611069573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108d91906143b9565b6110995761109961436a565b6110a284612af3565b60408051858152602081018490524281830152905133917f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94919081900360600190a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c8161111084826143a2565b6040805192835260208301919091520160405180910390a150506006805460ff191660011790555050565b6001546001600160a01b0316331461115257600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000806111818484610b57565b6001600160a01b038516600090815260176020908152604080832063ffffffff851684529091528120919250600190910190805b82548110156112095760008382815481106111d2576111d2614354565b906000526020600020015490506111e98188612bc6565b6111f390846143d6565b9250508080611201906143ee565b9150506111b5565b5095945050505050565b610e8083838360405180602001604052806000815250611a03565b600061123a8383612471565b9392505050565b6000818152600e6020908152604080832054600f909252822081633b9aca00811061126e5761126e614354565b6003020154600160801b9004600f0b9392505050565b6000546001600160a01b0316331461129b57600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0380821660009081526016602052604081205490911680156112e6578061123a565b5090919050565b6001600160a01b0381166112fe5750335b6113083382612c9a565b50565b60065460009060ff1660011461132057600080fd5b6006805460ff19166002179055611338838333612d0d565b90506006805460ff1916600117905592915050565b6001600160a01b038116600090815260086020526040812054610cc4565b601154600081815260036020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529091906113c38185612e64565b949350505050565b600061123a8383612f65565b6000610cc48261136b565b6000438211156113f4576113f461436a565b6011546000611403848361323e565b600081815260036020908152604080832081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060820152919250838310156115125760006003816114668660016143d6565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608083018290528501519192501461150c57826060015181606001516114d291906143a2565b836040015182604001516114e691906143a2565b60608501516114f5908a6143a2565b6114ff9190614407565b6115099190614426565b91505b50611561565b4382606001511461156157606082015161152c90436143a2565b604083015161153b90426143a2565b606084015161154a90896143a2565b6115549190614407565b61155e9190614426565b90505b61157a8282846040015161157591906143d6565b612e64565b9695505050505050565b6000546001600160a01b0316331461159b57600080fd5b6000818152601460205260409020546115b6906001906143a2565b60009182526014602052604090912055565b6001600160a01b03811660009081526018602052604081205463ffffffff168082036115f75750600092915050565b6001600160a01b03831660009081526017602052604081208161161b6001856142f6565b63ffffffff1663ffffffff16815260200190815260200160002060010190506000805b825481101561169257600083828154811061165b5761165b614354565b906000526020600020015490506116728142612bc6565b61167c90846143d6565b925050808061168a906143ee565b91505061163e565b50949350505050565b60065460ff166001146116ad57600080fd5b6006805460ff191660021790556116c43383612471565b6116d0576116d061436a565b60008281526010602090815260409182902082518084019093528054600f0b83526001015490820152816117065761170661436a565b60008160000151600f0b136117565760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b6044820152606401610f01565b428160200151116117795760405162461bcd60e51b8152600401610f019061443a565b611788838360008460026132c4565b50506006805460ff1916600117905550565b336001600160a01b038316036117b2576117b261436a565b336000818152600a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60065460ff1660011461183057600080fd5b6006805460ff191660021790556118473383612471565b6118535761185361436a565b600082815260106020908152604080832081518083019092528054600f0b825260010154918101919091529062093a808061188e85426143d6565b6118989190614426565b6118a29190614407565b9050428260200151116118e65760405162461bcd60e51b815260206004820152600c60248201526b131bd8dac8195e1c1a5c995960a21b6044820152606401610f01565b60008260000151600f0b136119315760405162461bcd60e51b8152602060048201526011602482015270139bdd1a1a5b99c81a5cc81b1bd8dad959607a1b6044820152606401610f01565b816020015181116119845760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e006044820152606401610f01565b611992630784ce00426143d6565b8111156119e15760405162461bcd60e51b815260206004820152601e60248201527f566f74696e67206c6f636b2063616e2062652034207965617273206d617800006044820152606401610f01565b6119f0846000838560036132c4565b50506006805460ff191660011790555050565b611a0f84848433612390565b823b15611b9c57604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290611a4890339088908790879060040161447e565b6020604051808303816000875af1925050508015611a83575060408051601f3d908101601f19168201909252611a80918101906144b1565b60015b611b2b573d808015611ab1576040519150601f19603f3d011682016040523d82523d6000602084013e611ab6565b606091505b508051600003611b235760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610f01565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14611b9a5760405162461bcd60e51b815260206004820152602660248201527f4552433732313a2045524337323152656365697665722072656a656374656420604482015265746f6b656e7360d01b6064820152608401610f01565b505b50505050565b6000546001600160a01b03163314611bb957600080fd5b6000908152601560205260409020805460ff19169055565b611c0f600060405180604001604052806000600f0b8152602001600081525060405180604001604052806000600f0b815260200160008152506124d7565b565b6040805180820182526005808252641d9953919560da1b60209283015282518084018452908152640312e302e360dc1b9082015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527fc792e9874e7b42c234d1e8448cec020a0f065019c8cd6f7ccdb65b8c110157e9818401527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c60608201524660808201523060a0808301919091528351808303909101815260c0820184528051908301207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60e08301526001600160a01b038a1661010083015261012082018990526101408083018990528451808403909101815261016083019094528351939092019290922061190160f01b61018084015261018283018290526101a2830181905290916000906101c20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015611dd0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611e4a5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e7660448201526d616c6964207369676e617475726560901b6064820152608401610f01565b6001600160a01b0381166000908152601960205260408120805491611e6e836143ee565b919050558914611ed35760405162461bcd60e51b815260206004820152602a60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e76604482015269616c6964206e6f6e636560b01b6064820152608401610f01565b87421115611f3a5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a2073696760448201526d1b985d1d5c9948195e1c1a5c995960921b6064820152608401610f01565b611f44818b612c9a565b505050505b505050505050565b6000818152600760205260409020546060906001600160a01b0316611fb85760405162461bcd60e51b815260206004820152601b60248201527f517565727920666f72206e6f6e6578697374656e7420746f6b656e00000000006044820152606401610f01565b60008281526010602090815260409182902082518084019093528054600f0b835260010154908201526002546001600160a01b031663dd9ec14984611ffd8142612bc6565b6020850151855160405160e086901b6001600160e01b0319168152600481019490945260248401929092526044830152600f0b6064820152608401600060405180830381865afa158015612055573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261123a91908101906144ce565b6000828152601460205260409020541580156120a8575060008281526015602052604090205460ff16155b6120c45760405162461bcd60e51b8152600401610f0190614380565b8082036120d057600080fd5b6120da3383612471565b6120e357600080fd5b6120ed3382612471565b6120f657600080fd5b6000828152601060208181526040808420815180830183528154600f90810b825260019283015482860190815288885295855283872084518086019095528054820b855290920154938301849052805194519095929490910b921115612160578260200151612166565b83602001515b604080518082018252600080825260208083018281528b835260108252848320935184546001600160801b0319166001600160801b03909116178455516001909301929092558251808401909352808352908201529091506121cb90879086906124d7565b6121d486612af3565b611f498583838660046132c4565b60065460009060ff166001146121f757600080fd5b6006805460ff1916600217905561220f848484612d0d565b90506006805460ff191660011790559392505050565b600061123a8383612bc6565b6000818152600b602052604081205443900361224f57506000919050565b610cc48242612bc6565b60065460ff1660011461226b57600080fd5b6006805460ff1916600217905560008281526010602090815260409182902082518084019093528054600f0b83526001015490820152816122ab57600080fd5b60008160000151600f0b136122fb5760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b6044820152606401610f01565b4281602001511161231e5760405162461bcd60e51b8152600401610f019061443a565b611788838360008460006132c4565b6000546001600160a01b0316331461234457600080fd5b6000818152601460205260409020546115b69060016143d6565b6000546001600160a01b0316331461237557600080fd5b6000908152601560205260409020805460ff19166001179055565b6000828152601460205260409020541580156123bb575060008281526015602052604090205460ff16155b6123d75760405162461bcd60e51b8152600401610f0190614380565b6123e18183612471565b6123ea57600080fd5b6123f484836134c9565b6123fe8483613530565b61241961240a856112bd565b612413856112bd565b846135b1565b6124238383613913565b6000828152600b60205260408082204390555183916001600160a01b0380871692908816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a450505050565b60008181526007602090815260408083205460098352818420546001600160a01b03918216808652600a855283862088841680885295529285205492938085149392909116149060ff1682806124c45750815b806124cc5750805b979650505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091526040805160808101825260008082526020820181905291810182905260608101919091526011546000908190871561264257428760200151118015612547575060008760000151600f0b135b1561258c57865161255d90630784ce009061453c565b600f0b6020808701919091528701516125779042906143a2565b8560200151612586919061457a565b600f0b85525b4286602001511180156125a6575060008660000151600f0b135b156125eb5785516125bc90630784ce009061453c565b600f0b6020808601919091528601516125d69042906143a2565b84602001516125e5919061457a565b600f0b84525b602080880151600090815260128252604090205490870151600f9190910b93501561264257866020015186602001510361262757829150612642565b602080870151600090815260129091526040902054600f0b91505b6040805160808101825260008082526020820152429181019190915243606082015281156126b7575060008181526003602090815260409182902082516080810184528154600f81810b8352600160801b909104900b9281019290925260018101549282019290925260029091015460608201525b6040810151816000428310156127045760408401516126d690426143a2565b60608501516126e590436143a2565b6126f790670de0b6b3a7640000614407565b6127019190614426565b90505b600062093a806127148186614426565b61271e9190614407565b905060005b60ff8110156128985761273962093a80836143d6565b915060004283111561274d57429250612761565b50600082815260126020526040902054600f0b5b61276b86846143a2565b876020015161277a919061457a565b8751889061278990839061460f565b600f0b9052506020870180518291906127a390839061465f565b600f90810b90915288516000910b121590506127be57600087525b60008760200151600f0b12156127d657600060208801525b60408088018490528501519295508592670de0b6b3a7640000906127fa90856143a2565b6128049086614407565b61280e9190614426565b856060015161281d91906143d6565b606088015261282d6001896143d6565b97504283036128425750436060870152612898565b6000888152600360209081526040918290208951918a01516001600160801b03908116600160801b029216919091178155908801516001820155606088015160029091015550612891816143ee565b9050612723565b505060118590558b1561292357886020015188602001516128b9919061460f565b846020018181516128ca919061465f565b600f0b905250885188516128de919061460f565b845185906128ed90839061465f565b600f90810b90915260208601516000910b1215905061290e57600060208501525b60008460000151600f0b121561292357600084525b6000858152600360209081526040918290208651918701516001600160801b03908116600160801b02921691909117815590850151600182015560608501516002909101558b15612ae557428b6020015111156129da576020890151612989908861465f565b96508a602001518a60200151036129ac5760208801516129a9908861460f565b96505b60208b810151600090815260129091526040902080546001600160801b0319166001600160801b0389161790555b428a602001511115612a35578a602001518a602001511115612a35576020880151612a05908761460f565b60208b810151600090815260129091526040902080546001600160801b0319166001600160801b03831617905595505b60008c8152600e6020526040812054612a4f9060016143d6565b905080600e60008f815260200190815260200160002081905550428960400181815250504389606001818152505088600f60008f815260200190815260200160002082633b9aca008110612aa557612aa5614354565b825160208401516001600160801b03908116600160801b029116176003919091029190910190815560408201516001820155606090910151600290910155505b505050505050505050505050565b612afd3382612471565b612b495760405162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665646044820152606401610f01565b6000818152600760205260408120546001600160a01b031690612b6c9083610d03565b612b80612b78826112bd565b6000846135b1565b612b8a3383613530565b60405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000828152600e6020526040812054808203612be6576000915050610cc4565b6000848152600f6020526040812082633b9aca008110612c0857612c08614354565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b602083015260018101549282018390526002015460608201529150612c5490856146ae565b8160200151612c63919061457a565b81518290612c7290839061460f565b600f90810b90915282516000910b12159050612c8d57600081525b51600f0b9150610cc49050565b6000612ca5836112bd565b6001600160a01b0384811660008181526016602052604080822080546001600160a01b031916888616908117909155905194955093928516927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4610e808382846139a9565b60008062093a8080612d1f86426143d6565b612d299190614426565b612d339190614407565b905060008511612d4257600080fd5b428111612da05760405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e207468652060448201526566757475726560d01b6064820152608401610f01565b612dae630784ce00426143d6565b811115612dfd5760405162461bcd60e51b815260206004820152601e60248201527f566f74696e67206c6f636b2063616e2062652034207965617273206d617800006044820152606401610f01565b600560008154612e0c906143ee565b90915550600554612e1d8482613d65565b5060008181526010602090815260409182902082518084019093528054600f0b835260019081015491830191909152612e5b918391899186916132c4565b95945050505050565b600080839050600062093a80808360400151612e809190614426565b612e8a9190614407565b905060005b60ff811015612f3d57612ea562093a80836143d6565b9150600085831115612eb957859250612ecd565b50600082815260126020526040902054600f0b5b6040840151612edc90846143a2565b8460200151612eeb919061457a565b84518590612efa90839061460f565b600f0b905250858303612f0d5750612f3d565b8084602001818151612f1f919061465f565b600f0b9052505060408301829052612f36816143ee565b9050612e8f565b5060008260000151600f0b1215612f5357600082525b50516001600160801b03169392505050565b600043821115612f7757612f7761436a565b6000838152600e6020526040812054815b608081101561301757818310156130175760006002612fa784866143d6565b612fb29060016143d6565b612fbc9190614426565b6000888152600f60205260409020909150869082633b9aca008110612fe357612fe3614354565b600302016002015411612ff857809350613006565b6130036001826143a2565b92505b50613010816143ee565b9050612f88565b506000858152600f6020526040812083633b9aca00811061303a5761303a614354565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b60208301526001810154928201929092526002909101546060820152601154909150600061308f878361323e565b600081815260036020908152604080832081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060820152919250808484101561316e5760006003816130f38760016143d6565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905286015191925061315091906143a2565b92508360400151816040015161316691906143a2565b915050613192565b606083015161317d90436143a2565b915082604001514261318f91906143a2565b90505b604083015182156131cf578284606001518c6131ae91906143a2565b6131b89084614407565b6131c29190614426565b6131cc90826143d6565b90505b60408701516131de90826143a2565b87602001516131ed919061457a565b875188906131fc90839061460f565b600f90810b90915288516000910b12905061322c57505093516001600160801b03169650610cc495505050505050565b60009950505050505050505050610cc4565b60008082815b60808110156132ba57818310156132ba576000600261326384866143d6565b61326e9060016143d6565b6132789190614426565b600081815260036020526040902060020154909150871061329b578093506132a9565b6132a66001826143a2565b92505b506132b3816143ee565b9050613244565b5090949350505050565b60135482906132d386826143d6565b6013556040805180820190915260008082526020820152825160208085015190830152600f0b815282518790849061330c90839061465f565b600f0b905250851561332057602083018690525b6000888152601060209081526040909120845181546001600160801b0319166001600160801b03909116178155908401516001909101556133628882856124d7565b33871580159061338457506004856004811115613381576133816146ed565b14155b1561342e576040516323b872dd60e01b81526001600160a01b038281166004830152306024830152604482018a90527f000000000000000000000000d83e12b3ad06914b4018f17ae47ae39f3584dfad16906323b872dd906064016020604051808303816000875af11580156133fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342291906143b9565b61342e5761342e61436a565b8360200151816001600160a01b03167fff04ccafc360e16b67d682d17bd9503c4c6b9a131f6be6325762dc9ffc7de6248b8b89426040516134729493929190614703565b60405180910390a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c836134a68a826143d6565b6040805192835260208301919091520160405180910390a1505050505050505050565b6000818152600760205260409020546001600160a01b038381169116146134f2576134f261436a565b6000818152600960205260409020546001600160a01b03161561352c57600081815260096020526040902080546001600160a01b03191690555b5050565b6000818152600760205260409020546001600160a01b038381169116146135595761355961436a565b600081815260076020526040902080546001600160a01b031916905561357f8282613dd6565b6001600160a01b03821660009081526008602052604081208054600192906135a89084906143a2565b90915550505050565b816001600160a01b0316836001600160a01b0316141580156135d35750600081115b15610e80576001600160a01b03831615613754576001600160a01b03831660009081526018602052604081205463ffffffff169081613637576001600160a01b03851660009081526017602090815260408083208380529091529020600101613679565b6001600160a01b03851660009081526017602052604081209061365b6001856142f6565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061368686613e95565b6001600160a01b038716600090815260176020908152604080832063ffffffff8516845290915281209192506001909101905b83548110156137135760008482815481106136d6576136d6614354565b90600052602060002001549050868114613700578254600181018455600084815260209020018190555b508061370b816143ee565b9150506136b9565b5061371f846001614741565b6001600160a01b0388166000908152601860205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03821615610e80576001600160a01b03821660009081526018602052604081205463ffffffff1690816137b3576001600160a01b038416600090815260176020908152604080832083805290915290206001016137f5565b6001600160a01b0384166000908152601760205260408120906137d76001856142f6565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061380285613e95565b6001600160a01b038616600090815260176020908152604080832063ffffffff85168452909152902083549192506001908101916104009161384491906143d6565b11156138625760405162461bcd60e51b8152600401610f0190614769565b60005b83548110156138b457600084828154811061388257613882614354565b6000918252602080832090910154855460018101875586845291909220015550806138ac816143ee565b915050613865565b508054600181810183556000838152602090209091018690556138d8908590614741565b6001600160a01b0387166000908152601860205260409020805463ffffffff9290921663ffffffff1990921691909117905550505050505050565b6000818152600760205260409020546001600160a01b0316156139385761393861436a565b600081815260076020908152604080832080546001600160a01b0319166001600160a01b03871690811790915580845260088084528285208054600c86528487208188528652848720889055878752600d8652938620939093559084529091528054600192906135a89084906143d6565b806001600160a01b0316826001600160a01b031614610e80576001600160a01b03821615613b5c576001600160a01b03821660009081526018602052604081205463ffffffff169081613a21576001600160a01b03841660009081526017602090815260408083208380529091529020600101613a63565b6001600160a01b038416600090815260176020526040812090613a456001856142f6565b63ffffffff1663ffffffff1681526020019081526020016000206001015b90506000613a7085613e95565b6001600160a01b038616600090815260176020908152604080832063ffffffff8516845290915281209192506001909101905b8354811015613b1b576000848281548110613ac057613ac0614354565b600091825260208083209091015480835260079091526040909120549091506001600160a01b03908116908a1614613b08578254600181018455600084815260209020018190555b5080613b13816143ee565b915050613aa3565b50613b27846001614741565b6001600160a01b0387166000908152601860205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03811615610e80576001600160a01b03811660009081526018602052604081205463ffffffff169081613bbb576001600160a01b03831660009081526017602090815260408083208380529091529020600101613bfd565b6001600160a01b038316600090815260176020526040812090613bdf6001856142f6565b63ffffffff1663ffffffff1681526020019081526020016000206001015b90506000613c0a84613e95565b6001600160a01b03808616600090815260176020908152604080832063ffffffff861684528252808320938b1683526008909152902054845492935060019091019161040090613c5b9083906143d6565b1115613c795760405162461bcd60e51b8152600401610f0190614769565b60005b8454811015613ccb576000858281548110613c9957613c99614354565b600091825260208083209091015486546001810188558784529190922001555080613cc3816143ee565b915050613c7c565b5060005b81811015613d1d576001600160a01b0389166000908152600c602090815260408083208484528252822054855460018101875586845291909220015580613d15816143ee565b915050613ccf565b50613d29856001614741565b6001600160a01b0387166000908152601860205260409020805463ffffffff9290921663ffffffff199092169190911790555050505050505050565b60006001600160a01b038316613d7d57613d7d61436a565b613d8b6000612413856112bd565b613d958383613913565b60405182906001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450600192915050565b6001600160a01b038216600090815260086020526040812054613dfb906001906143a2565b6000838152600d6020526040902054909150808203613e4a576001600160a01b0384166000908152600c602090815260408083208584528252808320839055858352600d909152812055611b9c565b6001600160a01b03939093166000908152600c6020908152604080832093835292815282822080548684528484208190558352600d9091528282209490945592839055908252812055565b6001600160a01b038116600090815260186020526040812054429063ffffffff168015801590613efe57506001600160a01b03841660009081526017602052604081208391613ee56001856142f6565b63ffffffff168152602081019190915260400160002054145b1561123a576113c36001826142f6565b6001600160e01b03198116811461130857600080fd5b600060208284031215613f3657600080fd5b813561123a81613f0e565b60005b83811015613f5c578181015183820152602001613f44565b83811115611b9c5750506000910152565b60008151808452613f85816020860160208601613f41565b601f01601f19169290920160200192915050565b60208152600061123a6020830184613f6d565b80356001600160a01b0381168114613fc357600080fd5b919050565b60008060408385031215613fdb57600080fd5b613fe483613fac565b946020939093013593505050565b60006020828403121561400457600080fd5b5035919050565b60006020828403121561401d57600080fd5b61123a82613fac565b6000806040838503121561403957600080fd5b50508035926020909101359150565b60008060006060848603121561405d57600080fd5b61406684613fac565b925061407460208501613fac565b9150604084013590509250925092565b801515811461130857600080fd5b600080604083850312156140a557600080fd5b6140ae83613fac565b915060208301356140be81614084565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614108576141086140c9565b604052919050565b600067ffffffffffffffff82111561412a5761412a6140c9565b50601f01601f191660200190565b6000806000806080858703121561414e57600080fd5b61415785613fac565b935061416560208601613fac565b925060408501359150606085013567ffffffffffffffff81111561418857600080fd5b8501601f8101871361419957600080fd5b80356141ac6141a782614110565b6140df565b8181528860208385010111156141c157600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060008060008060c087890312156141fc57600080fd5b61420587613fac565b95506020870135945060408701359350606087013560ff8116811461422957600080fd5b9598949750929560808101359460a0909101359350915050565b60008060006060848603121561425857600080fd5b833592506020840135915061426f60408501613fac565b90509250925092565b6000806040838503121561428b57600080fd5b61429483613fac565b91506142a260208401613fac565b90509250929050565b600080604083850312156142be57600080fd5b6142c783613fac565b9150602083013563ffffffff811681146140be57600080fd5b634e487b7160e01b600052601160045260246000fd5b600063ffffffff83811690831681811015614313576143136142e0565b039392505050565b634e487b7160e01b600052601260045260246000fd5b600063ffffffff808416806143485761434861431b565b92169190910492915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052600160045260246000fd5b602080825260089082015267185d1d1858da195960c21b604082015260600190565b6000828210156143b4576143b46142e0565b500390565b6000602082840312156143cb57600080fd5b815161123a81614084565b600082198211156143e9576143e96142e0565b500190565b600060018201614400576144006142e0565b5060010190565b6000816000190483118215151615614421576144216142e0565b500290565b6000826144355761443561431b565b500490565b60208082526024908201527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686040820152636472617760e01b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061157a90830184613f6d565b6000602082840312156144c357600080fd5b815161123a81613f0e565b6000602082840312156144e057600080fd5b815167ffffffffffffffff8111156144f757600080fd5b8201601f8101841361450857600080fd5b80516145166141a782614110565b81815285602083850101111561452b57600080fd5b612e5b826020830160208601613f41565b600081600f0b83600f0b806145535761455361431b565b60016001607f1b0319821460001982141615614571576145716142e0565b90059392505050565b600081600f0b83600f0b60016001607f1b036000821360008413838304851182821616156145aa576145aa6142e0565b60016001607f1b031960008512828116878305871216156145cd576145cd6142e0565b600087129250858205871284841616156145e9576145e96142e0565b858505871281841616156145ff576145ff6142e0565b5050509290910295945050505050565b600081600f0b83600f0b600081128160016001607f1b03190183128115161561463a5761463a6142e0565b8160016001607f1b03018313811615614655576146556142e0565b5090039392505050565b600081600f0b83600f0b600082128260016001607f1b0303821381151615614689576146896142e0565b8260016001607f1b03190382128116156146a5576146a56142e0565b50019392505050565b60008083128015600160ff1b8501841216156146cc576146cc6142e0565b6001600160ff1b03840183138116156146e7576146e76142e0565b50500390565b634e487b7160e01b600052602160045260246000fd5b84815260208101849052608081016005841061472f57634e487b7160e01b600052602160045260246000fd5b60408201939093526060015292915050565b600063ffffffff808316818516808303821115614760576147606142e0565b01949350505050565b60208082526023908201527f64737452657020776f756c64206861766520746f6f206d616e7920746f6b656e60408201526249647360e81b60608201526080019056fea2646970667358221220a924c6b408183e88d44826bd2b4de73ab466a4dd207271d230454486985d359464736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d83e12b3ad06914b4018f17ae47ae39f3584dfad00000000000000000000000021905102de17af6d4a4403258b7106a05f798bc9
-----Decoded View---------------
Arg [0] : token_addr (address): 0xD83e12B3Ad06914B4018F17AE47aE39F3584dfAd
Arg [1] : art_proxy (address): 0x21905102DE17aF6D4A4403258b7106a05F798bc9
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000d83e12b3ad06914b4018f17ae47ae39f3584dfad
Arg [1] : 00000000000000000000000021905102de17af6d4a4403258b7106a05f798bc9
Deployed Bytecode Sourcemap
13117:56061:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29386:136;;;;;;:::i;:::-;-1:-1:-1;;;;;;29481:33:0;29457:4;29481:33;;;:19;:33;;;;;;;;;29386:136;;;;565:14:1;;558:22;540:41;;528:2;513:18;29386:136:0;;;;;;;;34586:18;;;;;;;;;738:25:1;;;726:2;711:18;34586::0;592:177:1;16840:37:0;;;;;;;;;;;;;;;-1:-1:-1;;;16840:37:0;;;;;;;;;;;;:::i;60386:1064::-;;;;;;:::i;:::-;;:::i;:::-;;;2136:10:1;2124:23;;;2106:42;;2094:2;2079:18;60386:1064:0;1962:192:1;19805:117:0;;;;;;:::i;:::-;19864:7;19891:23;;;:13;:23;;;;;;-1:-1:-1;;;;;19891:23:0;;19805:117;;;;-1:-1:-1;;;;;2508:32:1;;;2490:51;;2478:2;2463:18;19805:117:0;2344:203:1;17021:110:0;;;;;;:::i;:::-;;:::i;:::-;;21026:658;;;;;;:::i;:::-;;:::i;56599:40::-;;;;;;:::i;:::-;;;;;;;;;;;;;;34333:60;;;;;;:::i;:::-;;:::i;:::-;;;;3252:2:1;3241:22;;;3223:41;;3300:22;;;;3295:2;3280:18;;3273:50;3339:18;;;3332:34;3397:2;3382:18;;3375:34;;;;3210:3;3195:19;34333:60:0;2996:419:1;55919:109:0;;;:::i;35580:150::-;;;;;;:::i;:::-;;:::i;58365:122::-;;58407:80;58365:122;;25794:174;;;;;;:::i;:::-;;:::i;43866:91::-;43937:12;43866:91;;48326:972;;;;;;:::i;:::-;;:::i;17139:120::-;;;;;;:::i;:::-;;:::i;30018:159::-;;;;;;:::i;:::-;-1:-1:-1;;;;;30128:28:0;;;;30104:4;30128:28;;;:20;:28;;;;;;;;:41;;;;;;;;;30018:159;16977:35;;17010:2;16977:35;;;;;4107:4:1;4095:17;;;4077:36;;4065:2;4050:18;16977:35:0;3935:184:1;61458:582:0;;;;;;:::i;:::-;;:::i;26699:173::-;;;;;;:::i;:::-;;:::i;23745:153::-;;;;;;:::i;:::-;;:::i;35179:194::-;;;;;;:::i;:::-;;:::i;:::-;;;4297:2:1;4286:22;;;;4268:41;;4256:2;4241:18;35179:194:0;4124:191:1;14690:20:0;;;;;-1:-1:-1;;;;;14690:20:0;;;56689:115;;;;;;:::i;:::-;;:::i;16930:40::-;;;;;;;;;;;;;;;-1:-1:-1;;;16930:40:0;;;;;14743:23;;;;;-1:-1:-1;;;;;14743:23:0;;;59491:187;;;;;;:::i;:::-;;:::i;67806:164::-;;;;;;:::i;:::-;;:::i;58812:41::-;;58849:4;58812:41;;18351:107;;;;;;:::i;:::-;18404:7;18431:19;;;:9;:19;;;;;;-1:-1:-1;;;;;18431:19:0;;18351:107;46061:166;;;;;;:::i;:::-;;:::i;19629:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;59105:48;;;;;;:::i;:::-;;;;;;;;;;;;;;;;19058:106;;;;;;:::i;:::-;;:::i;56202:198::-;;;;;;:::i;:::-;;:::i;34504:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;59234:38;;;;;;:::i;:::-;;;;;;;;;;;;;;14717:19;;;;;-1:-1:-1;;;;;14717:19:0;;;53649:140;;;;;;:::i;:::-;;:::i;62048:127::-;;;;;;:::i;:::-;;:::i;56646:34::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;34480:17;;;;;;53985:880;;;;;;:::i;:::-;;:::i;57225:147::-;;;;;;:::i;:::-;;:::i;59879:499::-;;;;;;:::i;:::-;;:::i;46851:503::-;;;;;;:::i;:::-;;:::i;22196:301::-;;;;;;:::i;:::-;;:::i;47490:724::-;;;;;;:::i;:::-;;:::i;34429:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4964:2:1;4953:22;;;;4935:41;;5007:2;4992:18;;4985:34;;;;4908:18;34429:44:0;4763:262:1;28081:998:0;;;;;;:::i;:::-;;:::i;56940:122::-;;;;;;:::i;:::-;;:::i;44015:106::-;;;:::i;67978:1197::-;;;;;;:::i;:::-;;:::i;17368:428::-;;;;;;:::i;:::-;;:::i;57380:722::-;;;;;;:::i;:::-;;:::i;14775:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;14775:43:0;;;;;;;;;46495:176;;;;;;:::i;:::-;;:::i;51511:130::-;;;;;;:::i;:::-;;:::i;34281:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;58581:117;;58627:71;58581:117;;51304:199;;;;;;:::i;:::-;;:::i;20131:153::-;;;;;;:::i;:::-;-1:-1:-1;;;;;20240:24:0;;;20215:4;20240:24;;;:16;:24;;;;;;;;20239:37;;;;;;;;;;;;;;;20131:153;44446:433;;;;;;:::i;:::-;;:::i;58968:68::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;35879:111;;;;;;:::i;:::-;35938:4;35962:16;;;:6;:16;;;;;:20;;;;35879:111;57070:147;;;;;;:::i;:::-;;:::i;14653:30::-;;;;;56812:120;;;;;;:::i;:::-;;:::i;60386:1064::-;-1:-1:-1;;;;;60508:23:0;;60467:6;60508:23;;;:14;:23;;;;;;;;60546:17;;;60542:58;;60587:1;60580:8;;;;;60542:58;-1:-1:-1;;;;;60658:20:0;;;;;;:11;:20;;;;;60710:9;;60679:16;60694:1;60679:12;:16;:::i;:::-;60658:38;;;;;;;;;;;;;-1:-1:-1;60658:38:0;:48;:61;60654:119;;60744:16;60759:1;60744:12;:16;:::i;:::-;60736:25;;;;;60654:119;-1:-1:-1;;;;;60834:20:0;;;;;;:11;:20;;;;;;;;:23;;;;;;;;:33;:45;-1:-1:-1;60830:86:0;;;60903:1;60896:8;;;;;60830:86;60928:12;;60970:16;60985:1;60970:12;:16;:::i;:::-;60955:31;;60997:423;61012:5;61004:13;;:5;:13;;;60997:423;;;61034:13;61076:1;61059:13;61067:5;61059;:13;:::i;:::-;61058:19;;;;:::i;:::-;61050:27;;:5;:27;:::i;:::-;-1:-1:-1;;;;;61143:20:0;;61119:21;61143:20;;;:11;:20;;;;;;;;:28;;;;;;;;;;61190:12;;61034:43;;-1:-1:-1;61143:28:0;61190:25;;;61186:223;;-1:-1:-1;61243:6:0;-1:-1:-1;61236:13:0;;-1:-1:-1;;;61236:13:0;61186:223;61275:12;;:24;-1:-1:-1;61271:138:0;;;61328:6;61320:14;;61271:138;;;61383:10;61392:1;61383:6;:10;:::i;:::-;61375:18;;61271:138;61019:401;;60997:423;;;-1:-1:-1;61437:5:0;-1:-1:-1;;60386:1064:0;;;;;:::o;17021:110::-;17095:4;;-1:-1:-1;;;;;17095:4:0;17081:10;:18;17073:27;;;;;;17111:4;:12;;-1:-1:-1;;;;;;17111:12:0;-1:-1:-1;;;;;17111:12:0;;;;;;;;;;17021:110::o;21026:658::-;21095:13;21111:19;;;:9;:19;;;;;;-1:-1:-1;;;;;21111:19:0;;21193:28;;;;;;21308:5;-1:-1:-1;;;;;21295:18:0;:9;-1:-1:-1;;;;;21295:18:0;;21287:27;;;;;;21356:18;21378:19;;;:9;:19;;;;;;;;;-1:-1:-1;;;;;21454:23:0;;;;;:16;:23;;;;;21401:10;21453:37;;;;;;;;;;21378:19;;:33;;21453:37;;21378:33;;21509:39;;;21526:22;21509:39;21501:48;;;;;;21589:23;;;;:13;:23;;;;;;:35;;-1:-1:-1;;;;;;21589:35:0;-1:-1:-1;;;;;21589:35:0;;;;;;;;;21640:36;;21589:23;;21640:36;;;;;;;21084:600;;;21026:658;;:::o;34333:60::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;34333:60:0;;;;;;;-1:-1:-1;34333:60:0;:::o;55919:109::-;55965:4;55989:31;56004:15;55989:14;:31::i;:::-;55982:38;;55919:109;:::o;35580:150::-;35661:4;35685:28;;;:18;:28;;;;;35714:4;35685:34;;;;;;;:::i;:::-;;;;:37;;;35678:44;;35580:150;;;;:::o;25794:174::-;25913:47;25927:5;25934:3;25939:8;25949:10;25913:13;:47::i;:::-;25794:174;;;:::o;48326:972::-;16515:14;;:30;:14;16381:1;16515:30;16507:39;;;;;;16557:14;:25;;-1:-1:-1;;16557:25:0;16424:1;16557:25;;;48399:40:::1;48418:10;48430:8:::0;48399:18:::1;:40::i;:::-;48392:48;;;;:::i;:::-;48459:21;::::0;;;:11:::1;:21;::::0;;;;;:26;:46;::::1;;;-1:-1:-1::0;48490:15:0::1;::::0;;;:5:::1;:15;::::0;;;;;::::1;;48489:16;48459:46;48451:67;;;;-1:-1:-1::0;;;48451:67:0::1;;;;;;;:::i;:::-;;;;;;;;;48531:28;48562:16:::0;;;:6:::1;:16;::::0;;;;;;;;48531:47;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;48597:15:::1;:30;;48589:65;;;::::0;-1:-1:-1;;;48589:65:0;;9584:2:1;48589:65:0::1;::::0;::::1;9566:21:1::0;9623:2;9603:18;;;9596:30;-1:-1:-1;;;9642:18:1;;;9635:52;9704:18;;48589:65:0::1;9382:346:1::0;48589:65:0::1;48690:14:::0;;48738:18:::1;::::0;;;;::::1;::::0;;-1:-1:-1;48738:18:0;;;::::1;::::0;;::::1;::::0;;;48719:16;;;:6:::1;:16:::0;;;;;;:37;;;;-1:-1:-1;;;;;;48719:37:0::1;-1:-1:-1::0;;;;;48719:37:0;;;::::1;::::0;;;;-1:-1:-1;48719:37:0;;::::1;::::0;48788:6:::1;::::0;48683:22:::1;::::0;;;::::1;::::0;48814:21:::1;48683:22:::0;48788:6;48814:21:::1;:::i;:::-;48805:6;:30:::0;49024:18:::1;::::0;;;;::::1;::::0;;;-1:-1:-1;49024:18:0;;;::::1;::::0;::::1;::::0;48993:50:::1;::::0;49005:8;;49015:7;;48993:11:::1;:50::i;:::-;49063:41;::::0;-1:-1:-1;;;49063:41:0;;49086:10:::1;49063:41;::::0;::::1;10037:51:1::0;10104:18;;;10097:34;;;49070:5:0::1;-1:-1:-1::0;;;;;49063:22:0::1;::::0;::::1;::::0;10010:18:1;;49063:41:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49056:49;;;;:::i;:::-;49143:15;49149:8;49143:5;:15::i;:::-;49176:54;::::0;;10594:25:1;;;10650:2;10635:18;;10628:34;;;49214:15:0::1;10678:18:1::0;;;10671:34;49176:54:0;;49185:10:::1;::::0;49176:54:::1;::::0;;;;;10582:2:1;49176:54:0;;::::1;49246:44;49253:13:::0;49268:21:::1;49284:5:::0;49253:13;49268:21:::1;:::i;:::-;49246:44;::::0;;10890:25:1;;;10946:2;10931:18;;10924:34;;;;10863:18;49246:44:0::1;;;;;;;-1:-1:-1::0;;16605:14:0;:29;;-1:-1:-1;;16605:29:0;16381:1;16605:29;;;-1:-1:-1;;48326:972:0:o;17139:120::-;17218:4;;-1:-1:-1;;;;;17218:4:0;17204:10;:18;17196:27;;;;;;17234:8;:17;;-1:-1:-1;;;;;;17234:17:0;-1:-1:-1;;;;;17234:17:0;;;;;;;;;;17139:120::o;61458:582::-;61561:4;61583:18;61604:37;61622:7;61631:9;61604:17;:37::i;:::-;-1:-1:-1;;;;;61701:20:0;;61674:24;61701:20;;;:11;:20;;;;;;;;:33;;;;;;;;;;61583:58;;-1:-1:-1;61701:42:0;;;;;61674:24;61779:231;61800:16;;61796:20;;61779:231;;;61838:8;61849:9;61859:1;61849:12;;;;;;;;:::i;:::-;;;;;;;;;61838:23;;61969:29;61983:3;61988:9;61969:13;:29::i;:::-;61961:37;;:5;:37;:::i;:::-;61953:45;;61823:187;61818:3;;;;;:::i;:::-;;;;61779:231;;;-1:-1:-1;62027:5:0;61458:582;-1:-1:-1;;;;;61458:582:0:o;26699:173::-;26822:42;26839:5;26846:3;26851:8;26822:42;;;;;;;;;;;;:16;:42::i;23745:153::-;23828:4;23852:38;23871:8;23881;23852:18;:38::i;:::-;23845:45;23745:153;-1:-1:-1;;;23745:153:0:o;35179:194::-;35246:6;35279:26;;;:16;:26;;;;;;;;;35323:18;:28;;;;;35279:26;35323:36;;;;;;;:::i;:::-;;;;:42;-1:-1:-1;;;35323:42:0;;;;;35179:194;-1:-1:-1;;;35179:194:0:o;56689:115::-;56765:5;;-1:-1:-1;;;;;56765:5:0;56751:10;:19;56743:28;;;;;;56782:5;:14;;-1:-1:-1;;;;;;56782:14:0;-1:-1:-1;;;;;56782:14:0;;;;;;;;;;56689:115::o;59491:187::-;-1:-1:-1;;;;;59588:21:0;;;59550:7;59588:21;;;:10;:21;;;;;;59550:7;;59588:21;59627;;:43;;59663:7;59627:43;;;-1:-1:-1;59651:9:0;;59620:50;-1:-1:-1;59491:187:0:o;67806:164::-;-1:-1:-1;;;;;67865:23:0;;67861:51;;-1:-1:-1;67902:10:0;67861:51;67930:32;67940:10;67952:9;67930;:32::i;:::-;67806:164;:::o;46061:166::-;16515:14;;46147:4;;16515:30;:14;16381:1;16515:30;16507:39;;;;;;16557:14;:25;;-1:-1:-1;;16557:25:0;16424:1;16557:25;;;46171:48:::1;46184:6:::0;46192:14;46208:10:::1;46171:12;:48::i;:::-;46164:55;;16605:14:::0;:29;;-1:-1:-1;;16605:29:0;16381:1;16605:29;;;46061:166;;-1:-1:-1;;46061:166:0:o;19058:106::-;-1:-1:-1;;;;;18781:27:0;;19116:4;18781:27;;;:19;:27;;;;;;19140:16;18700:116;56202:198;56286:5;;56255:4;56328:21;;;:13;:21;;;;;;;;56302:47;;;;;;;;;;;;;;;-1:-1:-1;;;56302:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56255:4;;56286:5;56367:25;56302:47;56390:1;56367:10;:25::i;:::-;56360:32;56202:198;-1:-1:-1;;;;56202:198:0:o;53649:140::-;53724:4;53748:33;53764:8;53774:6;53748:15;:33::i;62048:127::-;62118:4;62142:25;62157:9;62142:14;:25::i;53985:880::-;54044:4;54078:12;54068:6;:22;;54061:30;;;;:::i;:::-;54116:5;;54102:11;54152:33;54170:6;54116:5;54152:17;:33::i;:::-;54198:18;54219:27;;;:13;:27;;;;;;;;54198:48;;;;;;;;;;;;;;;-1:-1:-1;;;54198:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54132:53;;-1:-1:-1;54283:21:0;;;54279:465;;;54321:23;54347:13;54321:23;54361:16;:12;54376:1;54361:16;:::i;:::-;54347:31;;;;;;;;;;;;;;-1:-1:-1;54347:31:0;54321:57;;;;;;;;;;;;;;;-1:-1:-1;;;54321:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54397:9;;;54321:57;;-1:-1:-1;54397:27:0;54393:155;;54522:5;:9;;;54505:10;:14;;;:26;;;;:::i;:::-;54491:5;:8;;;54475:10;:13;;;:24;;;;:::i;:::-;54461:9;;;;54452:18;;:6;:18;:::i;:::-;54451:49;;;;:::i;:::-;54450:82;;;;:::i;:::-;54445:87;;54393:155;54306:253;54279:465;;;54597:12;54584:5;:9;;;:25;54580:153;;54707:9;;;;54692:24;;:12;:24;:::i;:::-;54678:8;;;;54660:26;;:15;:26;:::i;:::-;54646:9;;;;54637:18;;:6;:18;:::i;:::-;54636:51;;;;:::i;:::-;54635:82;;;;:::i;:::-;54630:87;;54580:153;54825:32;54836:5;54854:2;54843:5;:8;;;:13;;;;:::i;:::-;54825:10;:32::i;:::-;54818:39;53985:880;-1:-1:-1;;;;;;53985:880:0:o;57225:147::-;57298:5;;-1:-1:-1;;;;;57298:5:0;57284:10;:19;57276:28;;;;;;57339:21;;;;:11;:21;;;;;;:25;;57363:1;;57339:25;:::i;:::-;57315:21;;;;:11;:21;;;;;;:49;57225:147::o;59879:499::-;-1:-1:-1;;;;;59976:23:0;;59937:4;59976:23;;;:14;:23;;;;;;;;60014:17;;;60010:58;;-1:-1:-1;60055:1:0;;59879:499;-1:-1:-1;;59879:499:0:o;60010:58::-;-1:-1:-1;;;;;60105:20:0;;60078:24;60105:20;;;:11;:20;;;;;60078:24;60126:16;60141:1;60126:12;:16;:::i;:::-;60105:38;;;;;;;;;;;;;;;:47;;60078:74;;60163:10;60193:6;60188:160;60209:16;;60205:20;;60188:160;;;60247:8;60258:9;60268:1;60258:12;;;;;;;;:::i;:::-;;;;;;;;;60247:23;;60301:35;60315:3;60320:15;60301:13;:35::i;:::-;60293:43;;:5;:43;:::i;:::-;60285:51;;60232:116;60227:3;;;;;:::i;:::-;;;;60188:160;;;-1:-1:-1;60365:5:0;59879:499;-1:-1:-1;;;;59879:499:0:o;46851:503::-;16515:14;;:30;:14;16381:1;16515:30;16507:39;;;;;;16557:14;:25;;-1:-1:-1;;16557:25:0;16424:1;16557:25;;;46944:40:::1;46963:10;46975:8:::0;46944:18:::1;:40::i;:::-;46937:48;;;;:::i;:::-;46998:28;47029:16:::0;;;:6:::1;:16;::::0;;;;;;;;46998:47;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;47065:10;47058:18:::1;;;;:::i;:::-;47140:1;47123:7;:14;;;:18;;;47115:53;;;::::0;-1:-1:-1;;;47115:53:0;;11742:2:1;47115:53:0::1;::::0;::::1;11724:21:1::0;11781:2;11761:18;;;11754:30;-1:-1:-1;;;11800:18:1;;;11793:52;11862:18;;47115:53:0::1;11540:346:1::0;47115:53:0::1;47201:15;47187:7;:11;;;:29;47179:78;;;;-1:-1:-1::0;;;47179:78:0::1;;;;;;;:::i;:::-;47270:76;47283:8;47293:6;47301:1;47304:7;47313:32;47270:12;:76::i;:::-;-1:-1:-1::0;;16605:14:0;:29;;-1:-1:-1;;16605:29:0;16381:1;16605:29;;;-1:-1:-1;46851:503:0:o;22196:301::-;22352:10;-1:-1:-1;;;;;22339:23:0;;;22332:31;;;;:::i;:::-;22391:10;22374:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;22374:39:0;;;;;;;;;;;;:51;;-1:-1:-1;;22374:51:0;;;;;;;;;;22441:48;;540:41:1;;;22374:39:0;;22391:10;22441:48;;513:18:1;22441:48:0;;;;;;;22196:301;;:::o;47490:724::-;16515:14;;:30;:14;16381:1;16515:30;16507:39;;;;;;16557:14;:25;;-1:-1:-1;;16557:25:0;16424:1;16557:25;;;47596:40:::1;47615:10;47627:8:::0;47596:18:::1;:40::i;:::-;47589:48;;;;:::i;:::-;47650:28;47681:16:::0;;;:6:::1;:16;::::0;;;;;;;47650:47;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;;;34643:7:::1;::::0;47728:32:::1;47746:14:::0;47728:15:::1;:32;:::i;:::-;47727:41;;;;:::i;:::-;:48;;;;:::i;:::-;47708:67;;47847:15;47833:7;:11;;;:29;47825:54;;;::::0;-1:-1:-1;;;47825:54:0;;12498:2:1;47825:54:0::1;::::0;::::1;12480:21:1::0;12537:2;12517:18;;;12510:30;-1:-1:-1;;;12556:18:1;;;12549:42;12608:18;;47825:54:0::1;12296:336:1::0;47825:54:0::1;47915:1;47898:7;:14;;;:18;;;47890:48;;;::::0;-1:-1:-1;;;47890:48:0;;12839:2:1;47890:48:0::1;::::0;::::1;12821:21:1::0;12878:2;12858:18;;;12851:30;-1:-1:-1;;;12897:18:1;;;12890:47;12954:18;;47890:48:0::1;12637:341:1::0;47890:48:0::1;47971:7;:11;;;47957;:25;47949:69;;;::::0;-1:-1:-1;;;47949:69:0;;13185:2:1;47949:69:0::1;::::0;::::1;13167:21:1::0;13224:2;13204:18;;;13197:30;13263:33;13243:18;;;13236:61;13314:18;;47949:69:0::1;12983:355:1::0;47949:69:0::1;48052:25;34690:15;48052;:25;:::i;:::-;48037:11;:40;;48029:83;;;::::0;-1:-1:-1;;;48029:83:0;;13545:2:1;48029:83:0::1;::::0;::::1;13527:21:1::0;13584:2;13564:18;;;13557:30;13623:32;13603:18;;;13596:60;13673:18;;48029:83:0::1;13343:354:1::0;48029:83:0::1;48125:81;48138:8;48148:1;48151:11;48164:7;48173:32;48125:12;:81::i;:::-;-1:-1:-1::0;;16605:14:0;:29;;-1:-1:-1;;16605:29:0;16381:1;16605:29;;;-1:-1:-1;;47490:724:0:o;28081:998::-;28231:47;28245:5;28252:3;28257:8;28267:10;28231:13;:47::i;:::-;27199:20;;27247:8;28291:781;;28437:73;;-1:-1:-1;;;28437:73:0;;-1:-1:-1;;;;;28437:37:0;;;;;:73;;28475:10;;28487:5;;28494:8;;28504:5;;28437:73;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28437:73:0;;;;;;;;-1:-1:-1;;28437:73:0;;;;;;;;;;;;:::i;:::-;;;28433:628;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28778:6;:13;28795:1;28778:18;28774:272;;28821:60;;-1:-1:-1;;;28821:60:0;;14652:2:1;28821:60:0;;;14634:21:1;14691:2;14671:18;;;14664:30;14730:34;14710:18;;;14703:62;-1:-1:-1;;;14781:18:1;;;14774:48;14839:19;;28821:60:0;14450:414:1;28774:272:0;28996:6;28990:13;28981:6;28977:2;28973:15;28966:38;28433:628;-1:-1:-1;;;;;;28560:58:0;;-1:-1:-1;;;28560:58:0;28556:155;;28643:48;;-1:-1:-1;;;28643:48:0;;15071:2:1;28643:48:0;;;15053:21:1;15110:2;15090:18;;;15083:30;15149:34;15129:18;;;15122:62;-1:-1:-1;;;15200:18:1;;;15193:36;15246:19;;28643:48:0;14869:402:1;28556:155:0;28511:215;28433:628;28081:998;;;;:::o;56940:122::-;57014:5;;-1:-1:-1;;;;;57014:5:0;57000:10;:19;56992:28;;;;;;57049:5;57031:15;;;:5;:15;;;;;:23;;-1:-1:-1;;57031:23:0;;;56940:122::o;44015:106::-;44057:56;44069:1;44072:19;;;;;;;;44086:1;44072:19;;;;;;44089:1;44072:19;;;44093;;;;;;;;44107:1;44093:19;;;;;;44110:1;44093:19;;;44057:11;:56::i;:::-;44015:106::o;67978:1197::-;68284:4;;;;;;;;;;;;-1:-1:-1;;;68284:4:0;;;;;68325:7;;;;;;;;;;-1:-1:-1;;;68325:7:0;;;;68205:208;;58407:80;68205:208;;;15535:25:1;68268:22:0;15576:18:1;;;15569:34;68309:25:0;15619:18:1;;;15612:34;68353:13:0;15662:18:1;;;15655:34;68393:4:0;15705:19:1;;;;15698:61;;;;68205:208:0;;;;;;;;;;15507:19:1;;;68205:208:0;;68181:243;;;;;;58627:71;68480:57;;;16001:25:1;-1:-1:-1;;;;;16062:32:1;;16042:18;;;16035:60;16111:18;;;16104:34;;;16154:18;;;;16147:34;;;68480:57:0;;;;;;;;;;15973:19:1;;;68480:57:0;;;68456:92;;;;;;;;;;-1:-1:-1;;;68600:57:0;;;16450:27:1;16493:11;;;16486:27;;;16529:12;;;16522:28;;;68181:243:0;;-1:-1:-1;;16566:12:1;;68600:57:0;;;-1:-1:-1;;68600:57:0;;;;;;;;;68576:92;;68600:57;68576:92;;;;68679:17;68699:26;;;;;;;;;16816:25:1;;;16889:4;16877:17;;16857:18;;;16850:45;;;;16911:18;;;16904:34;;;16954:18;;;16947:34;;;68576:92:0;;-1:-1:-1;68679:17:0;68699:26;;16788:19:1;;68699:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68699:26:0;;-1:-1:-1;;68699:26:0;;;-1:-1:-1;;;;;;;68758:23:0;;68736:119;;;;-1:-1:-1;;;68736:119:0;;17194:2:1;68736:119:0;;;17176:21:1;17233:2;17213:18;;;17206:30;17272:34;17252:18;;;17245:62;-1:-1:-1;;;17323:18:1;;;17316:44;17377:19;;68736:119:0;16992:410:1;68736:119:0;-1:-1:-1;;;;;68897:17:0;;;;;;:6;:17;;;;;:19;;;;;;:::i;:::-;;;;;68888:5;:28;68866:120;;;;-1:-1:-1;;;68866:120:0;;17609:2:1;68866:120:0;;;17591:21:1;17648:2;17628:18;;;17621:30;17687:34;17667:18;;;17660:62;-1:-1:-1;;;17738:18:1;;;17731:40;17788:19;;68866:120:0;17407:406:1;68866:120:0;69038:6;69019:15;:25;;68997:121;;;;-1:-1:-1;;;68997:121:0;;18020:2:1;68997:121:0;;;18002:21:1;18059:2;18039:18;;;18032:30;18098:34;18078:18;;;18071:62;-1:-1:-1;;;18149:18:1;;;18142:44;18203:19;;68997:121:0;17818:410:1;68997:121:0;69136:31;69146:9;69157;69136;:31::i;:::-;69129:38;;;;67978:1197;;;;;;;:::o;17368:428::-;17489:1;17458:19;;;:9;:19;;;;;;17424:13;;-1:-1:-1;;;;;17458:19:0;17450:73;;;;-1:-1:-1;;;17450:73:0;;18435:2:1;17450:73:0;;;18417:21:1;18474:2;18454:18;;;18447:30;18513:29;18493:18;;;18486:57;18560:18;;17450:73:0;18233:351:1;17450:73:0;17534:28;17565:16;;;:6;:16;;;;;;;;;17534:47;;;;;;;;;;;;;;;;;;;;;17611:8;;-1:-1:-1;;;;;17611:8:0;17599:31;17572:8;17668:40;17572:8;17692:15;17668:13;:40::i;:::-;17723:11;;;;17761:14;;17599:189;;;;;;-1:-1:-1;;;;;;17599:189:0;;;;;;18820:25:1;;;;18861:18;;;18854:34;;;;18904:18;;;18897:34;17754:22:0;;18947:18:1;;;18940:34;18792:19;;17599:189:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;17599:189:0;;;;;;;;;;;;:::i;57380:722::-;57445:18;;;;:11;:18;;;;;;:23;:40;;;;-1:-1:-1;57473:12:0;;;;:5;:12;;;;;;;;57472:13;57445:40;57437:61;;;;-1:-1:-1;;;57437:61:0;;;;;;;:::i;:::-;57526:3;57517:5;:12;57509:21;;;;;;57549:37;57568:10;57580:5;57549:18;:37::i;:::-;57541:46;;;;;;57606:35;57625:10;57637:3;57606:18;:35::i;:::-;57598:44;;;;;;57655:29;57687:13;;;:6;:13;;;;;;;;57655:45;;;;;;;;;;;;;;;;;;;;;;;;;;57743:11;;;;;;;;;57711:43;;;;;;;;;;;;;;;;;;;;;;;;57791:15;;57830:12;;57655:45;;57711:43;;57784:23;;;;-1:-1:-1;57830:28:0;:58;;57876:8;:12;;;57830:58;;;57861:8;:12;;;57830:58;57917:19;;;;;;;;-1:-1:-1;57917:19:0;;;;;;;;;;57901:13;;;:6;:13;;;;;:35;;;;-1:-1:-1;;;;;;57901:35:0;-1:-1:-1;;;;;57901:35:0;;;;;;;-1:-1:-1;57901:35:0;;;;;;;57976:19;;;;;;;;;;;;;;;57819:69;;-1:-1:-1;57947:49:0;;57901:13;;57966:8;;57947:11;:49::i;:::-;58007:12;58013:5;58007;:12::i;:::-;58030:64;58043:3;58048:6;58056:3;58061:8;58071:22;58030:12;:64::i;46495:176::-;16515:14;;46598:4;;16515:30;:14;16381:1;16515:30;16507:39;;;;;;16557:14;:25;;-1:-1:-1;;16557:25:0;16424:1;16557:25;;;46622:41:::1;46635:6:::0;46643:14;46659:3;46622:12:::1;:41::i;:::-;46615:48;;16605:14:::0;:29;;-1:-1:-1;;16605:29:0;16381:1;16605:29;;;46495:176;;-1:-1:-1;;;46495:176:0:o;51511:130::-;51582:4;51606:27;51620:8;51630:2;51606:13;:27::i;51304:199::-;51364:4;51385:26;;;:16;:26;;;;;;51415:12;51385:42;;51381:56;;-1:-1:-1;51436:1:0;;51304:199;-1:-1:-1;51304:199:0:o;51381:56::-;51455:40;51469:8;51479:15;51455:13;:40::i;44446:433::-;16515:14;;:30;:14;16381:1;16515:30;16507:39;;;;;;16557:14;:25;;-1:-1:-1;;16557:25:0;16424:1;16557:25;;;:14;44559:16;;;:6:::1;:16;::::0;;;;;;;;44528:47;;;;::::1;::::0;;;;;::::1;;::::0;;16557:25;44528:47:::1;::::0;;;::::1;::::0;44596:10;44588:19:::1;;;::::0;::::1;;44671:1;44654:7;:14;;;:18;;;44646:53;;;::::0;-1:-1:-1;;;44646:53:0;;11742:2:1;44646:53:0::1;::::0;::::1;11724:21:1::0;11781:2;11761:18;;;11754:30;-1:-1:-1;;;11800:18:1;;;11793:52;11862:18;;44646:53:0::1;11540:346:1::0;44646:53:0::1;44732:15;44718:7;:11;;;:29;44710:78;;;;-1:-1:-1::0;;;44710:78:0::1;;;;;;;:::i;:::-;44799:72;44812:8;44822:6;44830:1;44833:7;44842:28;44799:12;:72::i;57070:147::-:0;57143:5;;-1:-1:-1;;;;;57143:5:0;57129:10;:19;57121:28;;;;;;57184:21;;;;:11;:21;;;;;;:25;;57208:1;57184:25;:::i;56812:120::-;56885:5;;-1:-1:-1;;;;;56885:5:0;56871:10;:19;56863:28;;;;;;56902:15;;;;:5;:15;;;;;:22;;-1:-1:-1;;56902:22:0;56920:4;56902:22;;;56812:120::o;24322:892::-;24476:21;;;;:11;:21;;;;;;:26;:46;;;;-1:-1:-1;24507:15:0;;;;:5;:15;;;;;;;;24506:16;24476:46;24468:67;;;;-1:-1:-1;;;24468:67:0;;;;;;;:::i;:::-;24585:37;24604:7;24613:8;24585:18;:37::i;:::-;24577:46;;;;;;24705:31;24720:5;24727:8;24705:14;:31::i;:::-;24811:33;24828:5;24835:8;24811:16;:33::i;:::-;24884:63;24904:16;24914:5;24904:9;:16::i;:::-;24922:14;24932:3;24922:9;:14::i;:::-;24938:8;24884:19;:63::i;:::-;24978:26;24990:3;24995:8;24978:11;:26::i;:::-;25090;;;;:16;:26;;;;;;25119:12;25090:41;;25176:30;25107:8;;-1:-1:-1;;;;;25176:30:0;;;;;;;;;;;24322:892;;;;:::o;23315:422::-;23399:4;23432:19;;;:9;:19;;;;;;;;;23549:13;:23;;;;;;-1:-1:-1;;;;;23432:19:0;;;23615:23;;;:16;:23;;;;;23484:17;;;23614:35;;;;;;;;;23432:19;;23484:17;;;;23549:23;;;;23537:35;;23614;;23484:17;;23667:35;;;23685:17;23667:35;:62;;;;23706:23;23667:62;23660:69;23315:422;-1:-1:-1;;;;;;;23315:422:0:o;36276:5882::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36568:5:0;;36490:17;;;;36590:13;;36586:1170;;36732:15;36715:10;:14;;;:32;:57;;;;;36771:1;36751:10;:17;;;:21;;;36715:57;36711:234;;;36807:17;;:28;;34748:15;;36807:28;:::i;:::-;36793:42;;:11;;;;:42;;;;36895:14;;;:32;;36912:15;;36895:32;:::i;:::-;36867:5;:11;;;:62;;;;:::i;:::-;36854:75;;;;36711:234;36980:15;36963:10;:14;;;:32;:57;;;;;37019:1;36999:10;:17;;;:21;;;36963:57;36959:234;;;37055:17;;:28;;34748:15;;37055:28;:::i;:::-;37041:42;;:11;;;;:42;;;;37143:14;;;:32;;37160:15;;37143:32;:::i;:::-;37115:5;:11;;;:62;;;;:::i;:::-;37102:75;;;;36959:234;37461:14;;;;;37447:29;;;;:13;:29;;;;;;37495:14;;;;37447:29;;;;;;-1:-1:-1;37495:19:0;37491:254;;37557:10;:14;;;37539:10;:14;;;:32;37535:195;;37609:10;37596:23;;37535:195;;;37695:14;;;;;37681:29;;;;:13;:29;;;;;;;;;;-1:-1:-1;37535:195:0;37794:66;;;;;;;;37768:23;37794:66;;;;;;;37824:15;37794:66;;;;;;;37846:12;37794:66;;;;37875:10;;37871:77;;-1:-1:-1;37915:21:0;;;;:13;:21;;;;;;;;;37902:34;;;;;;;;;;;;;;;-1:-1:-1;;;37902:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37871:77;37981:13;;;;:10;37958:20;38324:15;:31;-1:-1:-1;38320:160:0;;;38454:13;;;;38436:31;;:15;:31;:::i;:::-;38416:14;;;;38401:29;;:12;:29;:::i;:::-;38387:44;;34806:7;38387:44;:::i;:::-;38386:82;;;;:::i;:::-;38372:96;;38320:160;38719:8;34643:7;38731:22;34643:7;38731:15;:22;:::i;:::-;38730:31;;;;:::i;:::-;38719:42;;38781:6;38776:1383;38797:3;38793:1;:7;38776:1383;;;39003:11;34643:7;39003:11;;:::i;:::-;;;39033:14;39080:15;39074:3;:21;39070:168;;;39126:15;39120:21;;39070:168;;;-1:-1:-1;39200:18:0;;;;:13;:18;;;;;;;;39070:168;39308:21;39314:15;39308:3;:21;:::i;:::-;39275:10;:16;;;:56;;;;:::i;:::-;39256:75;;:10;;:75;;;;;:::i;:::-;;;;;-1:-1:-1;39350:16:0;;;:27;;39370:7;;39350:16;:27;;39370:7;;39350:27;:::i;:::-;;;;;;;;39400:15;;39418:1;39400:19;;;39396:127;;-1:-1:-1;39396:127:0;;39502:1;39484:19;;39396:127;39564:1;39545:10;:16;;;:20;;;39541:147;;;39667:1;39648:16;;;:20;39541:147;39746:13;;;;:19;;;39848:21;;;39724:3;;-1:-1:-1;39724:3:0;;34806:7;;39842:27;;39724:3;39842:27;:::i;:::-;39827:43;;:11;:43;:::i;:::-;39826:58;;;;:::i;:::-;39801:18;:22;;;:83;;;;:::i;:::-;39784:14;;;:100;39903:11;39913:1;39903:11;;:::i;:::-;;;39944:15;39937:3;:22;39933:211;;-1:-1:-1;40001:12:0;39984:14;;;:29;40036:5;;39933:211;40090:21;;;;:13;:21;;;;;;;;;:34;;;;;;-1:-1:-1;;;;;40090:34:0;;;-1:-1:-1;;;40090:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38802:3:0;;;:::i;:::-;;;38776:1383;;;-1:-1:-1;;40182:5:0;:14;;;40265:13;;40261:483;;40473:5;:11;;;40459:5;:11;;;:25;;;;:::i;:::-;40438:10;:16;;:47;;;;;;;:::i;:::-;;;;;-1:-1:-1;40533:10:0;;40520;;:23;;40533:10;40520:23;:::i;:::-;40500:44;;:10;;:44;;;;;:::i;:::-;;;;;;;;40563:16;;;;40582:1;40563:20;;;40559:81;;-1:-1:-1;40559:81:0;;40623:1;40604:16;;;:20;40559:81;40676:1;40658:10;:15;;;:19;;;40654:79;;;40716:1;40698:19;;40654:79;40806:21;;;;:13;:21;;;;;;;;;:34;;;;;;-1:-1:-1;;;;;40806:34:0;;;-1:-1:-1;;;40806:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;40857:13;;40853:1298;;41097:15;41080:10;:14;;;:32;41076:402;;;41227:11;;;;41213:25;;;;:::i;:::-;;;41279:10;:14;;;41261:10;:14;;;:32;41257:145;;41332:11;;;;41318:25;;;;:::i;:::-;;;41257:145;41434:14;;;;;41420:29;;;;:13;:29;;;;;;:42;;-1:-1:-1;;;;;;41420:42:0;-1:-1:-1;;;;;41420:42:0;;;;;41076:402;41515:15;41498:10;:14;;;:32;41494:344;;;41572:10;:14;;;41555:10;:14;;;:31;41551:209;;;41625:11;;;;41611:25;;;;:::i;:::-;41712:14;;;;;41698:29;;;;:13;:29;;;;;;:42;;-1:-1:-1;;;;;;41698:42:0;-1:-1:-1;;;;;41698:42:0;;;;;;-1:-1:-1;41551:209:0;41892:15;41910:26;;;:16;:26;;;;;;:30;;41939:1;41910:30;:::i;:::-;41892:48;;41986:10;41957:16;:26;41974:8;41957:26;;;;;;;;;;;:39;;;;42022:15;42011:5;:8;;:26;;;;;42064:12;42052:5;:9;;:24;;;;;42134:5;42091:18;:28;42110:8;42091:28;;;;;;;;;;;42120:10;42091:40;;;;;;;:::i;:::-;:48;;;;;;-1:-1:-1;;;;;42091:48:0;;;-1:-1:-1;;;42091:48:0;;;;:40;;;;;;;;;:48;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40853:1298:0;36421:5737;;;;;;;;;36276:5882;;;:::o;33600:486::-;33658:40;33677:10;33689:8;33658:18;:40::i;:::-;33650:85;;;;-1:-1:-1;;;33650:85:0;;21644:2:1;33650:85:0;;;21626:21:1;;;21663:18;;;21656:30;21722:34;21702:18;;;21695:62;21774:18;;33650:85:0;21442:356:1;33650:85:0;33748:13;18431:19;;;:9;:19;;;;;;-1:-1:-1;;;;;18431:19:0;;33821:29;;18431:19;33821:7;:29::i;:::-;33892:59;33912:16;33922:5;33912:9;:16::i;:::-;33938:1;33942:8;33892:19;:59::i;:::-;33987:38;34004:10;34016:8;33987:16;:38::i;:::-;34041:37;;34069:8;;34065:1;;-1:-1:-1;;;;;34041:37:0;;;;;34065:1;;34041:37;33639:447;33600:486;:::o;50765:531::-;50835:4;50866:26;;;:16;:26;;;;;;50907:11;;;50903:386;;50942:1;50935:8;;;;;50903:386;50976:23;51002:28;;;:18;:28;;;;;51031:6;51002:36;;;;;;;:::i;:::-;50976:62;;;;;;;;51002:36;;;;;;;;;50976:62;;;;;;;;-1:-1:-1;;;50976:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51098:34:0;;51105:2;51098:34;:::i;:::-;51072:10;:16;;;:61;;;;:::i;:::-;51053:80;;:10;;:80;;;;;:::i;:::-;;;;;;;;51152:15;;51170:1;51152:19;;;51148:79;;-1:-1:-1;51148:79:0;;51210:1;51192:19;;51148:79;51260:15;51253:23;;;-1:-1:-1;51241:36:0;;-1:-1:-1;51241:36:0;67217:441;67419:23;67445:20;67455:9;67445;:20::i;:::-;-1:-1:-1;;;;;67478:21:0;;;;;;;:10;:21;;;;;;:33;;-1:-1:-1;;;;;;67478:33:0;;;;;;;;;;67529:54;;67419:46;;-1:-1:-1;67478:33:0;67529:54;;;;;;67478:21;67529:54;67594:56;67612:9;67623:15;67640:9;67594:17;:56::i;45147:678::-;45234:4;;34643:7;;45271:32;45289:14;45271:15;:32;:::i;:::-;45270:41;;;;:::i;:::-;:48;;;;:::i;:::-;45251:67;;45385:1;45376:6;:10;45368:19;;;;;;45448:15;45434:11;:29;45426:80;;;;-1:-1:-1;;;45426:80:0;;22277:2:1;45426:80:0;;;22259:21:1;22316:2;22296:18;;;22289:30;22355:34;22335:18;;;22328:62;-1:-1:-1;;;22406:18:1;;;22399:36;22452:19;;45426:80:0;22075:402:1;45426:80:0;45540:25;34690:15;45540;:25;:::i;:::-;45525:11;:40;;45517:83;;;;-1:-1:-1;;;45517:83:0;;13545:2:1;45517:83:0;;;13527:21:1;13584:2;13564:18;;;13557:30;13623:32;13603:18;;;13596:60;13673:18;;45517:83:0;13343:354:1;45517:83:0;45615:7;;45613:9;;;;;:::i;:::-;;;;-1:-1:-1;45649:7:0;;45667:20;45673:3;45649:7;45667:5;:20::i;:::-;-1:-1:-1;45744:16:0;;;;:6;:16;;;;;;;;;45700:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;45713:8;;45723:6;;45731:11;;45700:12;:91::i;:::-;45809:8;45147:678;-1:-1:-1;;;;;45147:678:0:o;55120:791::-;55191:4;55208:23;55234:5;55208:31;;55250:8;34643:7;;55262:10;:13;;;:20;;;;:::i;:::-;55261:29;;;;:::i;:::-;55250:40;;55306:6;55301:472;55322:3;55318:1;:7;55301:472;;;55347:11;34643:7;55347:11;;:::i;:::-;;;55373:14;55416:1;55410:3;:7;55406:124;;;55444:1;55438:7;;55406:124;;;-1:-1:-1;55496:18:0;;;;:13;:18;;;;;;;;55406:124;55602:13;;;;55596:19;;:3;:19;:::i;:::-;55563:10;:16;;;:54;;;;:::i;:::-;55544:73;;:10;;:73;;;;;:::i;:::-;;;;;-1:-1:-1;55636:8:0;;;55632:54;;55665:5;;;55632:54;55720:7;55700:10;:16;;:27;;;;;;;:::i;:::-;;;;;-1:-1:-1;;55742:13:0;;;:19;;;55327:3;;;:::i;:::-;;;55301:472;;;;55807:1;55789:10;:15;;;:19;;;55785:71;;;55843:1;55825:19;;55785:71;-1:-1:-1;55886:15:0;-1:-1:-1;;;;;55873:30:0;;55120:791;-1:-1:-1;;;55120:791:0:o;51951:1690::-;52027:4;52165:12;52155:6;:22;;52148:30;;;;:::i;:::-;52217:9;52253:26;;;:16;:26;;;;;;52217:9;52290:391;52311:3;52307:1;:7;52290:391;;;52406:4;52398;:12;52394:58;52431:5;52394:58;52466:9;52498:1;52479:11;52486:4;52479;:11;:::i;:::-;:15;;52493:1;52479:15;:::i;:::-;52478:21;;;;:::i;:::-;52518:28;;;;:18;:28;;;;;52466:33;;-1:-1:-1;52560:6:0;;52466:33;52518:34;;;;;;;:::i;:::-;;;;:38;;;:48;52514:156;;52594:4;52587:11;;52514:156;;;52646:8;52653:1;52646:4;:8;:::i;:::-;52639:15;;52514:156;-1:-1:-1;52316:3:0;;;:::i;:::-;;;52290:391;;;-1:-1:-1;52693:19:0;52715:28;;;:18;:28;;;;;52744:4;52715:34;;;;;;;:::i;:::-;52693:56;;;;;;;;52715:34;;;;;;;;;52693:56;;;;;;;;-1:-1:-1;;;52693:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52779:5;;52693:56;;-1:-1:-1;;52809:36:0;52827:6;52779:5;52809:17;:36::i;:::-;52856:20;52879:21;;;:13;:21;;;;;;;;52856:44;;;;;;;;;;;;;;;-1:-1:-1;;;52856:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52795:50;;-1:-1:-1;52856:20:0;52965:18;;;52961:311;;;53000:20;53023:13;53000:20;53037:10;:6;53046:1;53037:10;:::i;:::-;53023:25;;;;;;;;;;;;;;-1:-1:-1;53023:25:0;53000:48;;;;;;;;;;;;;;;-1:-1:-1;;;53000:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53087:11;;;53000:48;;-1:-1:-1;53073:25:0;;53087:11;53073:25;:::i;:::-;53063:35;;53132:7;:10;;;53119:7;:10;;;:23;;;;:::i;:::-;53113:29;;52985:169;52961:311;;;53200:11;;;;53185:26;;:12;:26;:::i;:::-;53175:36;;53250:7;:10;;;53232:15;:28;;;;:::i;:::-;53226:34;;52961:311;53300:10;;;;53325:12;;53321:99;;53401:7;53385;:11;;;53376:6;:20;;;;:::i;:::-;53369:28;;:3;:28;:::i;:::-;53368:40;;;;:::i;:::-;53354:54;;;;:::i;:::-;;;53321:99;53489:9;;;;53476:22;;:10;:22;:::i;:::-;53447:6;:12;;;:53;;;;:::i;:::-;53432:68;;:6;;:68;;;;;:::i;:::-;;;;;;;;53515:11;;53530:1;53515:16;;;;-1:-1:-1;53511:123:0;;-1:-1:-1;;53568:11:0;;-1:-1:-1;;;;;53555:26:0;;-1:-1:-1;53548:33:0;;-1:-1:-1;;;;;;53548:33:0;53511:123;53621:1;53614:8;;;;;;;;;;;;;49902:583;49981:4;;50060:9;49981:4;50080:376;50101:3;50097:1;:7;50080:376;;;50196:4;50188;:12;50184:58;50221:5;50184:58;50256:9;50288:1;50269:11;50276:4;50269;:11;:::i;:::-;:15;;50283:1;50269:15;:::i;:::-;50268:21;;;;:::i;:::-;50308:19;;;;:13;:19;;;;;:23;;;50256:33;;-1:-1:-1;50308:33:0;-1:-1:-1;50304:141:0;;50369:4;50362:11;;50304:141;;;50421:8;50428:1;50421:4;:8;:::i;:::-;50414:15;;50304:141;-1:-1:-1;50106:3:0;;;:::i;:::-;;;50080:376;;;-1:-1:-1;50473:4:0;;49902:583;-1:-1:-1;;;;49902:583:0:o;42501:1357::-;42781:6;;42735:14;;42809:22;42825:6;42781;42809:22;:::i;:::-;42800:6;:31;-1:-1:-1;;;;;;;;;;;;;;;;;42923:14:0;;42939:11;;;;;42904:14;;;42884:67;;;;;43044:40;;43076:6;;42923:7;;43044:40;;43076:6;;43044:40;:::i;:::-;;;;;-1:-1:-1;43099:16:0;;43095:74;;43132:11;;;:25;;;43095:74;43179:16;;;;:6;:16;;;;;;;;:26;;;;-1:-1:-1;;;;;;43179:26:0;-1:-1:-1;;;;;43179:26:0;;;;;;;;;;-1:-1:-1;43179:26:0;;;;43457:42;43179:16;43479:10;43179:26;43457:11;:42::i;:::-;43527:10;43552:11;;;;;:53;;-1:-1:-1;43583:22:0;43567:12;:38;;;;;;;;:::i;:::-;;;43552:53;43548:149;;;43629:55;;-1:-1:-1;;;43629:55:0;;-1:-1:-1;;;;;22872:15:1;;;43629:55:0;;;22854:34:1;43670:4:0;22904:18:1;;;22897:43;22956:18;;;22949:34;;;43636:5:0;43629:26;;;;22789:18:1;;43629:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43622:63;;;;:::i;:::-;43746:7;:11;;;43722:4;-1:-1:-1;;;;;43714:75:0;;43728:8;43738:6;43759:12;43773:15;43714:75;;;;;;;;;:::i;:::-;;;;;;;;43805:45;43812:13;43827:22;43843:6;43812:13;43827:22;:::i;:::-;43805:45;;;10890:25:1;;;10946:2;10931:18;;10924:34;;;;10863:18;43805:45:0;;;;;;;42693:1165;;;;42501:1357;;;;;:::o;22645:324::-;22783:19;;;;:9;:19;;;;;;-1:-1:-1;;;;;22783:29:0;;;:19;;:29;22776:37;;;;:::i;:::-;22863:1;22828:23;;;:13;:23;;;;;;-1:-1:-1;;;;;22828:23:0;:37;22824:138;;22948:1;22914:23;;;:13;:23;;;;;:36;;-1:-1:-1;;;;;;22914:36:0;;;22824:138;22645:324;;:::o;33170:422::-;33308:19;;;;:9;:19;;;;;;-1:-1:-1;;;;;33308:28:0;;;:19;;:28;33301:36;;;;:::i;:::-;33407:1;33377:19;;;:9;:19;;;;;:32;;-1:-1:-1;;;;;;33377:32:0;;;33466:42;33492:5;33387:8;33466:25;:42::i;:::-;-1:-1:-1;;;;;33553:26:0;;;;;;:19;:26;;;;;:31;;33583:1;;33553:26;:31;;33583:1;;33553:31;:::i;:::-;;;;-1:-1:-1;;;;33170:422:0:o;62373:2026::-;62517:6;-1:-1:-1;;;;;62507:16:0;:6;-1:-1:-1;;;;;62507:16:0;;;:32;;;;;62538:1;62527:8;:12;62507:32;62503:1889;;;-1:-1:-1;;;;;62560:20:0;;;62556:837;;-1:-1:-1;;;;;62620:22:0;;62601:16;62620:22;;;:14;:22;;;;;;;;;62688:13;:135;;-1:-1:-1;;;;;62792:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;62688:135;;;-1:-1:-1;;;;;62725:19:0;;;;;;:11;:19;;;;;;62745:13;62757:1;62745:9;:13;:::i;:::-;62725:34;;;;;;;;;;;;;;;:43;;62688:135;62661:162;;62842:20;62865:34;62892:6;62865:26;:34::i;:::-;-1:-1:-1;;;;;62945:19:0;;62918:24;62945:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;62842:57;;-1:-1:-1;62945:83:0;;;;;63096:223;63117:16;;63113:20;;63096:223;;;63163:8;63174:9;63184:1;63174:12;;;;;;;;:::i;:::-;;;;;;;;;63163:23;;63220:8;63213:3;:15;63209:91;;63257:19;;;;;;;-1:-1:-1;63257:19:0;;;;;;;;;;63209:91;-1:-1:-1;63135:3:0;;;;:::i;:::-;;;;63096:223;;;-1:-1:-1;63364:13:0;:9;63376:1;63364:13;:::i;:::-;-1:-1:-1;;;;;63339:22:0;;;;;;:14;:22;;;;;:38;;-1:-1:-1;;63339:38:0;;;;;;;;;;;;-1:-1:-1;;;;62556:837:0;-1:-1:-1;;;;;63413:20:0;;;63409:972;;-1:-1:-1;;;;;63473:22:0;;63454:16;63473:22;;;:14;:22;;;;;;;;;63541:13;:135;;-1:-1:-1;;;;;63645:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;63541:135;;;-1:-1:-1;;;;;63578:19:0;;;;;;:11;:19;;;;;;63598:13;63610:1;63598:9;:13;:::i;:::-;63578:34;;;;;;;;;;;;;;;:43;;63541:135;63514:162;;63695:20;63718:34;63745:6;63718:26;:34::i;:::-;-1:-1:-1;;;;;63798:19:0;;63771:24;63798:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;63977:16;;63695:57;;-1:-1:-1;63798:83:0;;;;;58849:4;;63977:20;;:16;:20;:::i;:::-;:37;;63947:146;;;;-1:-1:-1;;;63947:146:0;;;;;;;:::i;:::-;64117:6;64112:152;64133:16;;64129:20;;64112:152;;;64179:8;64190:9;64200:1;64190:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;64225:19;;;;;;;;;;;;;;;;-1:-1:-1;64151:3:0;;;;:::i;:::-;;;;64112:152;;;-1:-1:-1;64282:24:0;;;;;;;;-1:-1:-1;64282:24:0;;;;;;;;;;;;64352:13;;:9;;:13;:::i;:::-;-1:-1:-1;;;;;64327:22:0;;;;;;:14;:22;;;;;:38;;;;;;;-1:-1:-1;;64327:38:0;;;;;;;;;-1:-1:-1;;;;62373:2026:0;;;:::o;30695:402::-;30855:1;30824:19;;;:9;:19;;;;;;-1:-1:-1;;;;;30824:19:0;:33;30817:41;;;;:::i;:::-;30898:19;;;;:9;:19;;;;;;;;:25;;-1:-1:-1;;;;;;30898:25:0;-1:-1:-1;;;;;30898:25:0;;;;;;;;18781:27;;;:19;:27;;;;;;;;30475:20;:25;;;;;:40;;;;;;;;:51;;;30537:27;;;:17;:27;;;;;:43;;;;31060:24;;;;;;:29;;-1:-1:-1;;30898:19:0;31060:29;;-1:-1:-1;;31060:29:0;:::i;64883:2326::-;65074:6;-1:-1:-1;;;;;65064:16:0;:6;-1:-1:-1;;;;;65064:16:0;;65060:2142;;-1:-1:-1;;;;;65101:20:0;;;65097:852;;-1:-1:-1;;;;;65161:22:0;;65142:16;65161:22;;;:14;:22;;;;;;;;;65229:13;:135;;-1:-1:-1;;;;;65333:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;65229:135;;;-1:-1:-1;;;;;65266:19:0;;;;;;:11;:19;;;;;;65286:13;65298:1;65286:9;:13;:::i;:::-;65266:34;;;;;;;;;;;;;;;:43;;65229:135;65202:162;;65383:20;65406:34;65433:6;65406:26;:34::i;:::-;-1:-1:-1;;;;;65486:19:0;;65459:24;65486:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;65383:57;;-1:-1:-1;65486:83:0;;;;;65644:231;65665:16;;65661:20;;65644:231;;;65711:8;65722:9;65732:1;65722:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;65761:14;;;:9;:14;;;;;;;;65722:12;;-1:-1:-1;;;;;;65761:14:0;;;:23;;;;65757:99;;65813:19;;;;;;;-1:-1:-1;65813:19:0;;;;;;;;;;65757:99;-1:-1:-1;65683:3:0;;;;:::i;:::-;;;;65644:231;;;-1:-1:-1;65920:13:0;:9;65932:1;65920:13;:::i;:::-;-1:-1:-1;;;;;65895:22:0;;;;;;:14;:22;;;;;:38;;-1:-1:-1;;65895:38:0;;;;;;;;;;;;-1:-1:-1;;;;65097:852:0;-1:-1:-1;;;;;65969:20:0;;;65965:1226;;-1:-1:-1;;;;;66029:22:0;;66010:16;66029:22;;;:14;:22;;;;;;;;;66097:13;:135;;-1:-1:-1;;;;;66201:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;66097:135;;;-1:-1:-1;;;;;66134:19:0;;;;;;:11;:19;;;;;;66154:13;66166:1;66154:9;:13;:::i;:::-;66134:34;;;;;;;;;;;;;;;:43;;66097:135;66070:162;;66251:20;66274:34;66301:6;66274:26;:34::i;:::-;-1:-1:-1;;;;;66354:19:0;;;66327:24;66354:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;66479:26;;;;;:19;:26;;;;;;66554:16;;66251:57;;-1:-1:-1;66354:83:0;;;;;58849:4;;66554:34;;66479:26;;66554:34;:::i;:::-;:51;;66524:160;;;;-1:-1:-1;;;66524:160:0;;;;;;;:::i;:::-;66741:6;66736:152;66757:16;;66753:20;;66736:152;;;66803:8;66814:9;66824:1;66814:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;66849:19;;;;;;;;;;;;;;;;-1:-1:-1;66775:3:0;;;;:::i;:::-;;;;66736:152;;;;66953:6;66948:169;66969:15;66965:1;:19;66948:169;;;-1:-1:-1;;;;;67025:27:0;;67014:8;67025:27;;;:20;:27;;;;;;;;:30;;;;;;;;67078:19;;;;;;;;;;;;;;;;67053:1;66986:3;67053:1;66986:3;:::i;:::-;;;;66948:169;;;-1:-1:-1;67162:13:0;:9;67174:1;67162:13;:::i;:::-;-1:-1:-1;;;;;67137:22:0;;;;;;:14;:22;;;;;:38;;;;;;;-1:-1:-1;;67137:38:0;;;;;;;;;-1:-1:-1;;;;;64883:2326:0;;;:::o;31437:426::-;31498:4;-1:-1:-1;;;;;31566:17:0;;31559:25;;;;:::i;:::-;31626:57;31654:1;31658:14;31668:3;31658:9;:14::i;31626:57::-;31756:26;31768:3;31773:8;31756:11;:26::i;:::-;31798:35;;31824:8;;-1:-1:-1;;;;;31798:35:0;;;31815:1;;31798:35;;31815:1;;31798:35;-1:-1:-1;31851:4:0;31437:426;;;;:::o;32043:1013::-;-1:-1:-1;;;;;18781:27:0;;32147:18;18781:27;;;:19;:27;;;;;;32168:19;;32186:1;;32168:19;:::i;:::-;32198:18;32219:27;;;:17;:27;;;;;;32147:40;;-1:-1:-1;32263:30:0;;;32259:790;;-1:-1:-1;;;;;32354:27:0;;32399:1;32354:27;;;:20;:27;;;;;;;;:42;;;;;;;;:46;;;32456:27;;;:17;:27;;;;;:31;32259:790;;;-1:-1:-1;;;;;32539:27:0;;;;32520:16;32539:27;;;:20;:27;;;;;;;;:42;;;;;;;;;;;32662;;;;;;:56;;;32774:30;;:17;:30;;;;;;:46;;;;32904;;;;33006:27;;;;;:31;32043:1013::o;64407:468::-;-1:-1:-1;;;;;64601:23:0;;64510:6;64601:23;;;:14;:23;;;;;;64552:15;;64601:23;;64655:17;;;;;:97;;-1:-1:-1;;;;;;64689:20:0;;;;;;:11;:20;;;;;64742:10;;64710:17;64726:1;64710:13;:17;:::i;:::-;64689:39;;;;;;;;;;;;;-1:-1:-1;64689:39:0;:49;:63;64655:97;64637:231;;;64786:17;64802:1;64786:13;:17;:::i;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;774:258::-;846:1;856:113;870:6;867:1;864:13;856:113;;;946:11;;;940:18;927:11;;;920:39;892:2;885:10;856:113;;;987:6;984:1;981:13;978:48;;;-1:-1:-1;;1022:1:1;1004:16;;997:27;774:258::o;1037:::-;1079:3;1117:5;1111:12;1144:6;1139:3;1132:19;1160:63;1216:6;1209:4;1204:3;1200:14;1193:4;1186:5;1182:16;1160:63;:::i;:::-;1277:2;1256:15;-1:-1:-1;;1252:29:1;1243:39;;;;1284:4;1239:50;;1037:258;-1:-1:-1;;1037:258:1:o;1300:220::-;1449:2;1438:9;1431:21;1412:4;1469:45;1510:2;1499:9;1495:18;1487:6;1469:45;:::i;1525:173::-;1593:20;;-1:-1:-1;;;;;1642:31:1;;1632:42;;1622:70;;1688:1;1685;1678:12;1622:70;1525:173;;;:::o;1703:254::-;1771:6;1779;1832:2;1820:9;1811:7;1807:23;1803:32;1800:52;;;1848:1;1845;1838:12;1800:52;1871:29;1890:9;1871:29;:::i;:::-;1861:39;1947:2;1932:18;;;;1919:32;;-1:-1:-1;;;1703:254:1:o;2159:180::-;2218:6;2271:2;2259:9;2250:7;2246:23;2242:32;2239:52;;;2287:1;2284;2277:12;2239:52;-1:-1:-1;2310:23:1;;2159:180;-1:-1:-1;2159:180:1:o;2552:186::-;2611:6;2664:2;2652:9;2643:7;2639:23;2635:32;2632:52;;;2680:1;2677;2670:12;2632:52;2703:29;2722:9;2703:29;:::i;2743:248::-;2811:6;2819;2872:2;2860:9;2851:7;2847:23;2843:32;2840:52;;;2888:1;2885;2878:12;2840:52;-1:-1:-1;;2911:23:1;;;2981:2;2966:18;;;2953:32;;-1:-1:-1;2743:248:1:o;3602:328::-;3679:6;3687;3695;3748:2;3736:9;3727:7;3723:23;3719:32;3716:52;;;3764:1;3761;3754:12;3716:52;3787:29;3806:9;3787:29;:::i;:::-;3777:39;;3835:38;3869:2;3858:9;3854:18;3835:38;:::i;:::-;3825:48;;3920:2;3909:9;3905:18;3892:32;3882:42;;3602:328;;;;;:::o;4320:118::-;4406:5;4399:13;4392:21;4385:5;4382:32;4372:60;;4428:1;4425;4418:12;4443:315;4508:6;4516;4569:2;4557:9;4548:7;4544:23;4540:32;4537:52;;;4585:1;4582;4575:12;4537:52;4608:29;4627:9;4608:29;:::i;:::-;4598:39;;4687:2;4676:9;4672:18;4659:32;4700:28;4722:5;4700:28;:::i;:::-;4747:5;4737:15;;;4443:315;;;;;:::o;5030:127::-;5091:10;5086:3;5082:20;5079:1;5072:31;5122:4;5119:1;5112:15;5146:4;5143:1;5136:15;5162:275;5233:2;5227:9;5298:2;5279:13;;-1:-1:-1;;5275:27:1;5263:40;;5333:18;5318:34;;5354:22;;;5315:62;5312:88;;;5380:18;;:::i;:::-;5416:2;5409:22;5162:275;;-1:-1:-1;5162:275:1:o;5442:186::-;5490:4;5523:18;5515:6;5512:30;5509:56;;;5545:18;;:::i;:::-;-1:-1:-1;5611:2:1;5590:15;-1:-1:-1;;5586:29:1;5617:4;5582:40;;5442:186::o;5633:888::-;5728:6;5736;5744;5752;5805:3;5793:9;5784:7;5780:23;5776:33;5773:53;;;5822:1;5819;5812:12;5773:53;5845:29;5864:9;5845:29;:::i;:::-;5835:39;;5893:38;5927:2;5916:9;5912:18;5893:38;:::i;:::-;5883:48;;5978:2;5967:9;5963:18;5950:32;5940:42;;6033:2;6022:9;6018:18;6005:32;6060:18;6052:6;6049:30;6046:50;;;6092:1;6089;6082:12;6046:50;6115:22;;6168:4;6160:13;;6156:27;-1:-1:-1;6146:55:1;;6197:1;6194;6187:12;6146:55;6233:2;6220:16;6258:48;6274:31;6302:2;6274:31;:::i;:::-;6258:48;:::i;:::-;6329:2;6322:5;6315:17;6369:7;6364:2;6359;6355;6351:11;6347:20;6344:33;6341:53;;;6390:1;6387;6380:12;6341:53;6445:2;6440;6436;6432:11;6427:2;6420:5;6416:14;6403:45;6489:1;6484:2;6479;6472:5;6468:14;6464:23;6457:34;6510:5;6500:15;;;;;5633:888;;;;;;;:::o;6526:618::-;6628:6;6636;6644;6652;6660;6668;6721:3;6709:9;6700:7;6696:23;6692:33;6689:53;;;6738:1;6735;6728:12;6689:53;6761:29;6780:9;6761:29;:::i;:::-;6751:39;;6837:2;6826:9;6822:18;6809:32;6799:42;;6888:2;6877:9;6873:18;6860:32;6850:42;;6942:2;6931:9;6927:18;6914:32;6986:4;6979:5;6975:16;6968:5;6965:27;6955:55;;7006:1;7003;6996:12;6955:55;6526:618;;;;-1:-1:-1;6526:618:1;;7081:3;7066:19;;7053:33;;7133:3;7118:19;;;7105:33;;-1:-1:-1;6526:618:1;-1:-1:-1;;6526:618:1:o;7149:322::-;7226:6;7234;7242;7295:2;7283:9;7274:7;7270:23;7266:32;7263:52;;;7311:1;7308;7301:12;7263:52;7347:9;7334:23;7324:33;;7404:2;7393:9;7389:18;7376:32;7366:42;;7427:38;7461:2;7450:9;7446:18;7427:38;:::i;:::-;7417:48;;7149:322;;;;;:::o;7476:260::-;7544:6;7552;7605:2;7593:9;7584:7;7580:23;7576:32;7573:52;;;7621:1;7618;7611:12;7573:52;7644:29;7663:9;7644:29;:::i;:::-;7634:39;;7692:38;7726:2;7715:9;7711:18;7692:38;:::i;:::-;7682:48;;7476:260;;;;;:::o;7741:350::-;7808:6;7816;7869:2;7857:9;7848:7;7844:23;7840:32;7837:52;;;7885:1;7882;7875:12;7837:52;7908:29;7927:9;7908:29;:::i;:::-;7898:39;;7987:2;7976:9;7972:18;7959:32;8031:10;8024:5;8020:22;8013:5;8010:33;8000:61;;8057:1;8054;8047:12;8096:127;8157:10;8152:3;8148:20;8145:1;8138:31;8188:4;8185:1;8178:15;8212:4;8209:1;8202:15;8228:221;8267:4;8296:10;8356;;;;8326;;8378:12;;;8375:38;;;8393:18;;:::i;:::-;8430:13;;8228:221;-1:-1:-1;;;8228:221:1:o;8454:127::-;8515:10;8510:3;8506:20;8503:1;8496:31;8546:4;8543:1;8536:15;8570:4;8567:1;8560:15;8586:191;8625:1;8651:10;8688:2;8685:1;8681:10;8710:3;8700:37;;8717:18;;:::i;:::-;8755:10;;8751:20;;;;;8586:191;-1:-1:-1;;8586:191:1:o;8782:127::-;8843:10;8838:3;8834:20;8831:1;8824:31;8874:4;8871:1;8864:15;8898:4;8895:1;8888:15;8914:127;8975:10;8970:3;8966:20;8963:1;8956:31;9006:4;9003:1;8996:15;9030:4;9027:1;9020:15;9046:331;9248:2;9230:21;;;9287:1;9267:18;;;9260:29;-1:-1:-1;;;9320:2:1;9305:18;;9298:38;9368:2;9353:18;;9046:331::o;9733:125::-;9773:4;9801:1;9798;9795:8;9792:34;;;9806:18;;:::i;:::-;-1:-1:-1;9843:9:1;;9733:125::o;10142:245::-;10209:6;10262:2;10250:9;10241:7;10237:23;10233:32;10230:52;;;10278:1;10275;10268:12;10230:52;10310:9;10304:16;10329:28;10351:5;10329:28;:::i;10969:128::-;11009:3;11040:1;11036:6;11033:1;11030:13;11027:39;;;11046:18;;:::i;:::-;-1:-1:-1;11082:9:1;;10969:128::o;11102:135::-;11141:3;11162:17;;;11159:43;;11182:18;;:::i;:::-;-1:-1:-1;11229:1:1;11218:13;;11102:135::o;11242:168::-;11282:7;11348:1;11344;11340:6;11336:14;11333:1;11330:21;11325:1;11318:9;11311:17;11307:45;11304:71;;;11355:18;;:::i;:::-;-1:-1:-1;11395:9:1;;11242:168::o;11415:120::-;11455:1;11481;11471:35;;11486:18;;:::i;:::-;-1:-1:-1;11520:9:1;;11415:120::o;11891:400::-;12093:2;12075:21;;;12132:2;12112:18;;;12105:30;12171:34;12166:2;12151:18;;12144:62;-1:-1:-1;;;12237:2:1;12222:18;;12215:34;12281:3;12266:19;;11891:400::o;13702:489::-;-1:-1:-1;;;;;13971:15:1;;;13953:34;;14023:15;;14018:2;14003:18;;13996:43;14070:2;14055:18;;14048:34;;;14118:3;14113:2;14098:18;;14091:31;;;13896:4;;14139:46;;14165:19;;14157:6;14139:46;:::i;14196:249::-;14265:6;14318:2;14306:9;14297:7;14293:23;14289:32;14286:52;;;14334:1;14331;14324:12;14286:52;14366:9;14360:16;14385:30;14409:5;14385:30;:::i;18985:635::-;19065:6;19118:2;19106:9;19097:7;19093:23;19089:32;19086:52;;;19134:1;19131;19124:12;19086:52;19167:9;19161:16;19200:18;19192:6;19189:30;19186:50;;;19232:1;19229;19222:12;19186:50;19255:22;;19308:4;19300:13;;19296:27;-1:-1:-1;19286:55:1;;19337:1;19334;19327:12;19286:55;19366:2;19360:9;19391:48;19407:31;19435:2;19407:31;:::i;19391:48::-;19462:2;19455:5;19448:17;19502:7;19497:2;19492;19488;19484:11;19480:20;19477:33;19474:53;;;19523:1;19520;19513:12;19474:53;19536:54;19587:2;19582;19575:5;19571:14;19566:2;19562;19558:11;19536:54;:::i;19625:305::-;19664:1;19706;19702:2;19691:17;19743:1;19739:2;19728:17;19764:3;19754:37;;19771:18;;:::i;:::-;-1:-1:-1;;;;;;19807:48:1;;-1:-1:-1;;19857:15:1;;19803:70;19800:96;;;19876:18;;:::i;:::-;19910:14;;;19625:305;-1:-1:-1;;;19625:305:1:o;19935:698::-;19974:7;20022:1;20018:2;20007:17;20059:1;20055:2;20044:17;-1:-1:-1;;;;;20142:1:1;20137:3;20133:11;20172:1;20167:3;20163:11;20219:3;20215:2;20211:12;20206:3;20203:21;20198:2;20194;20190:11;20186:39;20183:65;;;20228:18;;:::i;:::-;-1:-1:-1;;;;;;20334:1:1;20325:11;;20352;;;20374:13;;;20365:23;;20348:41;20345:67;;;20392:18;;:::i;:::-;20440:1;20435:3;20431:11;20421:21;;20489:3;20485:2;20480:13;20475:3;20471:23;20466:2;20462;20458:11;20454:41;20451:67;;;20498:18;;:::i;:::-;20565:3;20561:2;20556:13;20551:3;20547:23;20542:2;20538;20534:11;20530:41;20527:67;;;20574:18;;:::i;:::-;-1:-1:-1;;;20614:13:1;;;;;19935:698;-1:-1:-1;;;;;19935:698:1:o;20638:398::-;20677:4;20722:1;20718:2;20707:17;20759:1;20755:2;20744:17;20789:1;20784:3;20780:11;20873:3;-1:-1:-1;;;;;20832:39:1;20828:49;20823:3;20819:59;20814:2;20807:10;20803:76;20800:102;;;20882:18;;:::i;:::-;20971:3;-1:-1:-1;;;;;20931:44:1;20926:3;20922:54;20918:2;20914:63;20911:89;;;20980:18;;:::i;:::-;-1:-1:-1;21017:13:1;;;20638:398;-1:-1:-1;;;20638:398:1:o;21041:396::-;21080:3;21124:1;21120:2;21109:17;21161:1;21157:2;21146:17;21191:1;21186:3;21182:11;21270:3;-1:-1:-1;;;;;21230:44:1;21225:3;21221:54;21216:2;21209:10;21205:71;21202:97;;;21279:18;;:::i;:::-;21373:3;-1:-1:-1;;;;;21332:39:1;21328:49;21323:3;21319:59;21315:2;21311:68;21308:94;;;21382:18;;:::i;:::-;-1:-1:-1;21418:13:1;;21041:396;-1:-1:-1;;;21041:396:1:o;21803:267::-;21842:4;21871:9;;;21896:10;;-1:-1:-1;;;21915:19:1;;21908:27;;21892:44;21889:70;;;21939:18;;:::i;:::-;-1:-1:-1;;;;;21986:27:1;;21979:35;;21971:44;;21968:70;;;22018:18;;:::i;:::-;-1:-1:-1;;22055:9:1;;21803:267::o;22482:127::-;22543:10;22538:3;22534:20;22531:1;22524:31;22574:4;22571:1;22564:15;22598:4;22595:1;22588:15;22994:557;23238:25;;;23294:2;23279:18;;23272:34;;;23225:3;23210:19;;23336:1;23325:13;;23315:144;;23381:10;23376:3;23372:20;23369:1;23362:31;23416:4;23413:1;23406:15;23444:4;23441:1;23434:15;23315:144;23490:2;23475:18;;23468:34;;;;23533:2;23518:18;23511:34;22994:557;;-1:-1:-1;;22994:557:1:o;23556:228::-;23595:3;23623:10;23660:2;23657:1;23653:10;23690:2;23687:1;23683:10;23721:3;23717:2;23713:12;23708:3;23705:21;23702:47;;;23729:18;;:::i;:::-;23765:13;;23556:228;-1:-1:-1;;;;23556:228:1:o;23789:399::-;23991:2;23973:21;;;24030:2;24010:18;;;24003:30;24069:34;24064:2;24049:18;;24042:62;-1:-1:-1;;;24135:2:1;24120:18;;24113:33;24178:3;24163:19;;23789:399::o
Swarm Source
ipfs://a924c6b408183e88d44826bd2b4de73ab466a4dd207271d230454486985d3594
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.