Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
VotingEscrow
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2024-12-26 */ /** *v2.0.4 *0x9d8e8b3a4559626e5ee2112156fddd28d91b6504 *Submitted for verification at FtmScan.com on 2023-06-29 */ /**v2.0.3 *0x61bc8103b8c2dcf901a0a38fad2247e75650baab *Submitted for verification at FtmScan.com on 2023-06-27 */ /*v1.3.16 *0x0e719d1bbed13e9d0a49d37c6fd287f42ce5f862 *Submitted for verification at FtmScan.com on 2023-03-31 */ /**v1.3.15 *0x0A3e8cb1679bDA43055F2e28a24fdF5Bf5F7454C *Submitted for verification at FtmScan.com on 2023-03-29 */ /**v1.3.1 *0xD4F24608ca843140E3921B97c546329a1D8c8E1b *Submitted for verification at FtmScan.com on 2022-11-28 */ /**v1.2 *0xb03e993c59461d05b0e8e7124ba44ff56b2de151 *Submitted for verification at FtmScan.com on 2022-11-13 */ /** * EQUALIZER EXCHANGE * The New Liquidity Hub of Fantom chain! * https://equalizer.exchange (Dapp) * https://discord.gg/MaMhbgHMby (Community) * * * * Version: 2.0.3 * * ChangeLog: * - Limit Max NFTs per wallet in preparation for Equity * * * * Contributors: * - Andre Cronje, Solidly.Exchange * - Velodrome.finance Team * - @smartcoding51 * - 543#3017 (Sam), ftm.guru & Equalizer.exchange * * * SPDX-License-Identifier: UNLICENSED */ // File: contracts/interfaces/IVeArtProxy.sol pragma solidity 0.8.9; interface IVeArtProxy { // solhint-disable-next-line 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.9; interface IERC20 { function totalSupply() external view returns (uint256); function transfer(address recipient, uint amount) external returns (bool); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); 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: contracts/libraries/Base64.sol pragma solidity 0.8.9; /// [MIT License] /// @title Base64 /// @notice Provides a function for encoding some bytes in base64 /// @author Brecht Devos <[email protected]> library Base64 { bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /// @notice Encodes some bytes to the base64 representation function encode(bytes memory data) internal pure returns (string memory) { uint len = data.length; if (len == 0) return ""; // multiply by 4/3 rounded up uint encodedLen = 4 * ((len + 2) / 3); // Add some extra buffer at the end bytes memory result = new bytes(encodedLen + 32); bytes memory table = TABLE; assembly { let tablePtr := add(table, 1) let resultPtr := add(result, 32) for { let i := 0 } lt(i, len) { } { i := add(i, 3) let input := and(mload(add(data, i)), 0xffffff) let out := mload(add(tablePtr, and(shr(18, input), 0x3F))) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)) out := shl(224, out) mstore(resultPtr, out) resultPtr := add(resultPtr, 4) } switch mod(len, 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } mstore(result, encodedLen) } return string(result); } } // File: @openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.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 IERC721ReceiverUpgradeable { /** * @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-upgradeable/governance/utils/IVotesUpgradeable.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 IVotesUpgradeable { /** * @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-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable { /** * @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-upgradeable/token/ERC721/IERC721Upgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @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-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } } // File: contracts/VotingEscrow.sol pragma solidity 0.8.9; /** * @title Voting Escrow * @notice veNFT implementation that escrows ERC-20 tokens in the form of an ERC-721 NFT * Votes have a weight depending on time, so that users are committed to the future of (whatever they are voting for) * @dev Vote weight decays linearly over time. Lock time cannot be more than `MAXTIME` (26 weeks). */ contract VotingEscrow is Initializable, IERC721Upgradeable, IERC721MetadataUpgradeable, IVotesUpgradeable { 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); /*////////////////////////////////////////////////////////////// Initialize //////////////////////////////////////////////////////////////*/ address public token; address public voter; address public team; address public ms; 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; /// @dev reentrancy guard bool internal _locked; address public oldVoter; uint8 public MAX_HOLDINGS; /********************************************************************************************/ /*****************************************NON-STORAGE****************************************/ /********************************************************************************************/ /// NON-STORAGE /** * @notice Contract Initialize * @param token_addr `EQUAL` token address */ function initialize( address token_addr, address art_proxy ) public initializer { token = token_addr; voter = msg.sender; team = msg.sender; ms = msg.sender; artProxy = art_proxy; MAX_HOLDINGS = 20; 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 //////////////////////////////////////////////////////////////*/ modifier nonReentrant() { require(!_locked, "No re-entrancy"); _locked = true; _; _locked = false; } /*/////////////////////////////////////////////////////////////// METADATA & STORAGE //////////////////////////////////////////////////////////////*/ string constant public version = "3.0.0"; uint8 constant public decimals = 18; function name() public view returns(string memory) { return string(abi.encodePacked(IERC20(token).name()," Voting Escrow ",unicode"🔐")); } function symbol() public view returns(string memory) { return string(abi.encodePacked("ve",IERC20(token).symbol())); } /*/////////////////////////////////////////////////////////////// FUNCTIONS //////////////////////////////////////////////////////////////*/ 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( _balance(_to) <= MAX_HOLDINGS , "Exceeds Max NFT Holding Limit per address!"); 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 IERC721ReceiverUpgradeable(_to).onERC721Received(msg.sender, _from, _tokenId, _data) returns (bytes4 response) { if (response != IERC721ReceiverUpgradeable(_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 = 26 * 7 * 86400; int128 internal constant iMAXTIME = 26 * 7 * 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 27 weeks! // 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, "Invalid amount"); // 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) { require( _balance(_to) <= MAX_HOLDINGS , "Exceeds Max NFT Holding Limit per address!"); 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 26 weeks 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) public 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 26 weeks max"); _deposit_for(_tokenId, 0, unlock_time, __locked, DepositType.INCREASE_UNLOCK_TIME); } function maxLockMultiple(uint[] memory _ids) external { uint _max = block.timestamp / WEEK * WEEK + MAXTIME; for(uint i; i<_ids.length; i++) { uint _old = locked[_ids[i]].end / WEEK * WEEK ; if(_old < _max) { increase_unlock_time( _ids[i] , MAXTIME ) ; } } } function maxLockAll() external { uint _bal = _balance(msg.sender); uint _max = block.timestamp / WEEK * WEEK + MAXTIME; for(uint i; i<_bal; i++) { uint _nid = ownerToNFTokenIdList[msg.sender][i]; uint _old = locked[_nid].end / WEEK * WEEK ; if(_old < _max) { increase_unlock_time( _nid , MAXTIME ) ; } } } /// @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); } /// v1.5.2 : Helper view functions function totalTokens() public view returns (uint) { return(tokenId - _balance(address(0)) ); } function totalTokensMinted() public view returns (uint) { return(tokenId); } function totalTokensBurned() public view returns (uint) { return _balance(address(0)); } function tokensOfOwner(address _usr) public view returns (uint[] memory) { uint _tbal = _balance(_usr); uint[] memory _ra = new uint[](_tbal); for(uint i;i<_tbal;i++) { _ra[i] = ownerToNFTokenIdList[_usr][i]; } return _ra; } /*/////////////////////////////////////////////////////////////// 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 == oldVoter || msg.sender == voter, "Not old/old Voter"); attachments[_tokenId] = attachments[_tokenId] + 1; } function detach(uint _tokenId) external { require(msg.sender == oldVoter || msg.sender == voter, "Not old/old 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 bool public delegationsAllowed; /// @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 { require(delegationsAllowed, "Delegations Not Allowed!"); 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 { require(delegationsAllowed, "Delegations Not Allowed!"); 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); } /// @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_for(uint _tokenId, uint _value) external nonReentrant { require(msg.sender == team, "not team"); 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); } function reset() external { require(msg.sender == ms, "!ms"); team = ms; } function setOldVoter(address _ov) external { require(msg.sender == ms, "!ms"); oldVoter = _ov; } function setNewVoter(address _v) external { require(msg.sender == ms, "!ms"); voter = _v; } function setMaxHoldings(uint8 _m) external { require(msg.sender == ms, "!ms"); MAX_HOLDINGS = _m; } function setDelegationsAllowed(bool _a) external { require(msg.sender == ms, "!ms"); delegationsAllowed = _a; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":"uint8","name":"version","type":"uint8"}],"name":"Initialized","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":[],"name":"MAX_HOLDINGS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"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":[],"name":"delegationsAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_value","type":"uint256"}],"name":"increase_amount_for","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":"token_addr","type":"address"},{"internalType":"address","name":"art_proxy","type":"address"}],"name":"initialize","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":[],"name":"maxLockAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"maxLockMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"merge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ms","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":[],"name":"oldVoter","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"reset","outputs":[],"stateMutability":"nonpayable","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":"bool","name":"_a","type":"bool"}],"name":"setDelegationsAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_m","type":"uint8"}],"name":"setMaxHoldings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_v","type":"address"}],"name":"setNewVoter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ov","type":"address"}],"name":"setOldVoter","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":[{"internalType":"address","name":"_usr","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":[],"name":"totalTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokensBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokensMinted","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
608060405234801561001057600080fd5b506155f180620000216000396000f3fe608060405234801561001057600080fd5b50600436106104c25760003560e01c80638462151c11610278578063c1f0fb9f1161015c578063e441135c116100ce578063f096636811610092578063f096636814610c6f578063f1127ed814610c7c578063f8a0576314610ca7578063fbd3a29d14610cca578063fc0c546a14610cdd578063fd4a77f114610cf657600080fd5b8063e441135c14610bc6578063e7a324dc14610be6578063e7e242d414610c0d578063e985e9c514610c20578063ee99fe2814610c5c57600080fd5b8063d157e30111610120578063d157e30114610b3f578063d1c2babb14610b47578063d1febfb914610b5a578063d4e54c3b14610b98578063d826f88f14610bab578063e0514aba14610bb357600080fd5b8063c1f0fb9f14610aeb578063c2c4c5c114610afe578063c3cda52014610b06578063c568d48014610b19578063c87b56dd14610b2c57600080fd5b8063986b7d8a116101f5578063a2ee4a7c116101b9578063a2ee4a7c14610a3e578063a4d855df14610a52578063aab8015814610a65578063b45a3c0e14610a78578063b88d4fde14610ac0578063b94ef2b814610ad357600080fd5b8063986b7d8a146109df5780639ab24eb0146109f2578063a0b2d57f14610a05578063a183af5214610a18578063a22cb46514610a2b57600080fd5b8063900cf0cf1161023c578063900cf0cf146109955780639506ec8e1461099e57806395d89b41146109b15780639624d163146109b9578063981b24d0146109cc57600080fd5b80638462151c1461091957806385f2aef2146109395780638c2c9baf1461094c5780638e539e8c1461095f5780638fbb38ff1461097257600080fd5b806342842e0e116103aa57806362af40731161031c57806370a08231116102e057806370a08231146108a05780637116c60c146108b357806371197484146108c65780637d549e99146108e95780637e1c0c09146108f15780637ecebe00146108f957600080fd5b806362af40731461080b5780636352211e1461081e57806365fc3873146108475780636f5488371461085a5780636fcfff451461087a57600080fd5b80634bc2a6571161036e5780634bc2a6571461079257806354fd4d50146107a55780635594a045146107c9578063587cde1e146107dc5780635c19a95c146107ef5780635f5b0c321461080257600080fd5b806342842e0e14610720578063430c208114610733578063461f711c1461074657806346c96aac1461076c578063485cc9551461077f57600080fd5b806318160ddd116104435780632e1a7d4d116104075780632e1a7d4d146106845780632e720f7d146106975780632f745c59146106aa578063313ce567146106e05780633a46b1a8146106fa5780633b1e371f1461070d57600080fd5b806318160ddd146106295780631c984bc31461063157806320606b701461064457806323b872dd1461066b57806325a58b561461067e57600080fd5b8063095cf5c61161048a578063095cf5c61461059e578063095ea7b3146105b35780630d6a2033146105c65780631376f3da146105e657806314a3c8c31461062157600080fd5b806301ffc9a7146104c7578063047fc9aa1461050957806306fdde03146105205780630758c7d814610535578063081812fc1461055d575b600080fd5b6104f46104d5366004614aed565b6001600160e01b03191660009081526006602052604090205460ff1690565b60405190151581526020015b60405180910390f35b61051260155481565b604051908152602001610500565b610528610d09565b6040516105009190614b62565b610548610543366004614b91565b610db9565b60405163ffffffff9091168152602001610500565b61058661056b366004614bbb565b6000908152600b60205260409020546001600160a01b031690565b6040516001600160a01b039091168152602001610500565b6105b16105ac366004614bd4565b610f2a565b005b6105b16105c1366004614b91565b610f63565b6105126105d4366004614bbb565b60166020526000908152604090205481565b6105f96105f4366004614bef565b61104c565b60408051600f95860b81529390940b6020840152928201526060810191909152608001610500565b6105b1611093565b61051261114c565b61051261063f366004614bef565b61115c565b6105127f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6105b1610679366004614c11565b61118e565b43610512565b6105b1610692366004614bbb565b61119a565b6105b16106a5366004614bd4565b611456565b6105126106b8366004614b91565b6001600160a01b03919091166000908152600e60209081526040808320938352929052205490565b6106e8601281565b60405160ff9091168152602001610500565b610512610708366004614b91565b61148f565b6105b161071b366004614bd4565b61152e565b6105b161072e366004614c11565b61157a565b6104f4610741366004614b91565b611595565b610759610754366004614bbb565b6115a8565b604051600f9190910b8152602001610500565b600154610586906001600160a01b031681565b6105b161078d366004614c4d565b6115eb565b6105b16107a0366004614bd4565b61187e565b610528604051806040016040528060058152602001640332e302e360dc1b81525081565b600454610586906001600160a01b031681565b6105866107ea366004614bd4565b611895565b6105b16107fd366004614bd4565b6118c5565b61051261040081565b6105b1610819366004614c91565b611930565b61058661082c366004614bbb565b6000908152600960205260409020546001600160a01b031690565b610512610855366004614bef565b61197a565b610512610868366004614bbb565b600d6020526000908152604090205481565b610548610888366004614bd4565b601b6020526000908152604090205463ffffffff1681565b6105126108ae366004614bd4565b6119c9565b6105126108c1366004614bbb565b6119d4565b6107596108d4366004614bbb565b601460205260009081526040902054600f0b81565b600754610512565b610512611a34565b610512610907366004614bd4565b601c6020526000908152604090205481565b61092c610927366004614bd4565b611a4d565b6040516105009190614cac565b600254610586906001600160a01b031681565b61051261095a366004614bef565b611b0b565b61051261096d366004614bbb565b611b17565b6104f4610980366004614bbb565b60176020526000908152604090205460ff1681565b61051260135481565b6105b16109ac366004614bd4565b611b22565b610528611b74565b6105b16109c7366004614bef565b611c10565b6105126109da366004614bbb565b611d4e565b6105b16109ed366004614bbb565b611ef0565b610512610a00366004614bd4565b611f85565b600354610586906001600160a01b031681565b6105b1610a26366004614bef565b612056565b6105b1610a39366004614cfe565b61209c565b6008546106e890600160a81b900460ff1681565b6105b1610a60366004614bef565b612121565b6105b1610a73366004614d35565b612313565b610aa6610a86366004614bbb565b60126020526000908152604090208054600190910154600f9190910b9082565b60408051600f9390930b8352602083019190915201610500565b6105b1610ace366004614dc1565b612350565b6008546105869061010090046001600160a01b031681565b6105b1610af9366004614bbb565b6124fb565b6105b161252a565b6105b1610b14366004614e6c565b61256a565b6105b1610b27366004614ec4565b6128d3565b610528610b3a366004614bbb565b612997565b610512612ad2565b6105b1610b55366004614bef565b612ade565b6105f9610b68366004614bbb565b600560205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b610512610ba6366004614f6a565b612c44565b6105b1612c94565b610512610bc1366004614bef565b612ce2565b610512610bd4366004614bbb565b60106020526000908152604090205481565b6105127fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b610512610c1b366004614bbb565b612cee565b6104f4610c2e366004614c4d565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b6105b1610c6a366004614bef565b612d16565b6019546104f49060ff1681565b610512610c8a366004614f9f565b601a60209081526000928352604080842090915290825290205481565b610512610cb5366004614bbb565b60009081526012602052604090206001015490565b6105b1610cd8366004614bbb565b612e35565b600054610586906201000090046001600160a01b031681565b6105b1610d04366004614bbb565b612eb7565b6060600060029054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015610d5957600080fd5b505afa158015610d6d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d959190810190614fd4565b604051602001610da59190615042565b604051602081830303815290604052905090565b6001600160a01b0382166000908152601b602052604081205463ffffffff1680610de7576000915050610f24565b6001600160a01b0384166000908152601a602052604081208491610e0c600185615098565b63ffffffff16815260208101919091526040016000205411610e3b57610e33600182615098565b915050610f24565b6001600160a01b0384166000908152601a60209081526040808320838052909152902054831015610e70576000915050610f24565b600080610e7e600184615098565b90505b8163ffffffff168163ffffffff161115610f1f5760006002610ea38484615098565b610ead91906150d3565b610eb79083615098565b6001600160a01b0388166000908152601a6020908152604080832063ffffffff851684529091529020805491925090871415610ef957509350610f2492505050565b8054871115610f0a57819350610f18565b610f15600183615098565b92505b5050610e81565b509150505b92915050565b6002546001600160a01b03163314610f4157600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600960205260409020546001600160a01b031680610f8557600080fd5b806001600160a01b0316836001600160a01b03161415610fa457600080fd5b6000828152600960209081526040808320546001600160a01b038581168552600c845282852033808752945291909320549216149060ff168180610fe55750805b610fee57600080fd5b6000848152600b602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a45050505050565b601160205281600052604060002081633b9aca00811061106b57600080fd5b6003020180546001820154600290920154600f82810b9550600160801b90920490910b925084565b600061109e33612ee9565b9050600062eff10062093a806110b481426150f6565b6110be919061510a565b6110c89190615129565b905060005b8281101561114757336000908152600e60209081526040808320848452825280832054808452601290925282206001015490919062093a80906111119082906150f6565b61111b919061510a565b905083811015611132576111328262eff100612121565b5050808061113f90615141565b9150506110cd565b505050565b6000611157426119d4565b905090565b600082815260116020526040812082633b9aca00811061117e5761117e61515c565b6003020160010154905092915050565b61114783838333612f04565b60085460ff16156111c65760405162461bcd60e51b81526004016111bd90615172565b60405180910390fd5b6008805460ff191660011790556111dd3382613007565b6111e9576111e961519a565b600081815260166020526040902054158015611214575060008181526017602052604090205460ff16155b6112305760405162461bcd60e51b81526004016111bd906151b0565b60008181526012602090815260409182902082518084019093528054600f0b8352600101549082018190524210156112a35760405162461bcd60e51b8152602060048201526016602482015275546865206c6f636b206469646e27742065787069726560501b60448201526064016111bd565b8051604080518082018252600080825260208083018281528783526012909152929020905181546001600160801b0319166001600160801b039091161781559051600190910155601554600f9190910b906112fe82826151d2565b6015556040805180820190915260008082526020820152611322908590859061306d565b60005460405163a9059cbb60e01b815233600482015260248101849052620100009091046001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561137357600080fd5b505af1158015611387573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ab91906151e9565b6113b7576113b761519a565b6113c08461368a565b60408051858152602081018490524281830152905133917f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94919081900360600190a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c8161142e84826151d2565b6040805192835260208301919091520160405180910390a150506008805460ff191690555050565b6002546001600160a01b0316331461146d57600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60008061149c8484610db9565b6001600160a01b0385166000908152601a6020908152604080832063ffffffff851684529091528120919250600190910190805b82548110156115245760008382815481106114ed576114ed61515c565b90600052602060002001549050611504818861374b565b61150e9084615129565b925050808061151c90615141565b9150506114d0565b5095945050505050565b6003546001600160a01b031633146115585760405162461bcd60e51b81526004016111bd90615206565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b61114783838360405180602001604052806000815250612350565b60006115a18383613007565b9392505050565b6000818152601060209081526040808320546011909252822081633b9aca0081106115d5576115d561515c565b6003020154600160801b9004600f0b9392505050565b600054610100900460ff161580801561160b5750600054600160ff909116105b806116255750303b158015611625575060005460ff166001145b6116885760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016111bd565b6000805460ff1916600117905580156116ab576000805461ff0019166101001790555b6000805462010000600160b01b031916620100006001600160a01b038681169190910291909117825560018054336001600160a01b03199182168117835560028054831682179055600380548316909117905560048054909116928616929092179091556008805460ff60a81b1916600560aa1b179055437f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746be55427f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bd5560066020527f477a984de5936bcb02475f64e0ea676103106ac0785c67bf7e9e846450b51ef6805460ff1990811683179091557fd544553a2e70858ffdf1e1169f6f124859d29ddf2686bcabf4e6f71bc63044228054821683179055635b5e139f60e01b83527fcc41b8fe3dd37df8e4a56c49f4e83a8fb6899f1fe8f1ddc40678281e8ec62212805490911690911790556007546040519091309160008051602061559c833981519152908290a4600754604051600090309060008051602061559c833981519152908390a48015611147576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6001546001600160a01b0316331461155857600080fd5b6001600160a01b0380821660009081526018602052604081205490911680156118be57806115a1565b5090919050565b60195460ff166119125760405162461bcd60e51b815260206004820152601860248201527744656c65676174696f6e73204e6f7420416c6c6f7765642160401b60448201526064016111bd565b6001600160a01b0381166119235750335b61192d338261381d565b50565b6003546001600160a01b0316331461195a5760405162461bcd60e51b81526004016111bd90615206565b6008805460ff909216600160a81b0260ff60a81b19909216919091179055565b60085460009060ff16156119a05760405162461bcd60e51b81526004016111bd90615172565b6008805460ff191660011790556119b8838333613890565b6008805460ff191690559392505050565b6000610f2482612ee9565b601354600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060820152909190611a2c8185613a1c565b949350505050565b6000611a406000612ee9565b60075461115791906151d2565b60606000611a5a83612ee9565b905060008167ffffffffffffffff811115611a7757611a77614d52565b604051908082528060200260200182016040528015611aa0578160200160208202803683370190505b50905060005b82811015611b03576001600160a01b0385166000908152600e602090815260408083208484529091529020548251839083908110611ae657611ae661515c565b602090810291909101015280611afb81615141565b915050611aa6565b509392505050565b60006115a18383613b1e565b6000610f24826119d4565b6003546001600160a01b03163314611b4c5760405162461bcd60e51b81526004016111bd90615206565b600880546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6060600060029054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611bc457600080fd5b505afa158015611bd8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c009190810190614fd4565b604051602001610da59190615223565b60085460ff1615611c335760405162461bcd60e51b81526004016111bd90615172565b6008805460ff19166001179055600254336001600160a01b0390911614611c875760405162461bcd60e51b81526020600482015260086024820152676e6f74207465616d60c01b60448201526064016111bd565b60008281526012602090815260409182902082518084019093528054600f0b8352600101549082015281611cbd57611cbd61519a565b60008160000151600f0b13611d0d5760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b60448201526064016111bd565b42816020015111611d305760405162461bcd60e51b81526004016111bd9061524d565b611d3f83836000846002613dfb565b50506008805460ff1916905550565b600043821115611d6057611d6061519a565b6013546000611d6f8483613ffa565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606082015291925083831015611e7e576000600581611dd2866001615129565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905285015191925014611e785782606001518160600151611e3e91906151d2565b83604001518260400151611e5291906151d2565b6060850151611e61908a6151d2565b611e6b919061510a565b611e7591906150f6565b91505b50611ecd565b43826060015114611ecd576060820151611e9890436151d2565b6040830151611ea790426151d2565b6060840151611eb690896151d2565b611ec0919061510a565b611eca91906150f6565b90505b611ee682828460400151611ee19190615129565b613a1c565b9695505050505050565b60085461010090046001600160a01b0316331480611f1857506001546001600160a01b031633145b611f585760405162461bcd60e51b81526020600482015260116024820152702737ba1037b63217b7b632102b37ba32b960791b60448201526064016111bd565b600081815260166020526040902054611f73906001906151d2565b60009182526016602052604090912055565b6001600160a01b0381166000908152601b602052604081205463ffffffff1680611fb25750600092915050565b6001600160a01b0383166000908152601a6020526040812081611fd6600185615098565b63ffffffff1663ffffffff16815260200190815260200160002060010190506000805b825481101561204d5760008382815481106120165761201661515c565b9060005260206000200154905061202d814261374b565b6120379084615129565b925050808061204590615141565b915050611ff9565b50949350505050565b60085460ff16156120795760405162461bcd60e51b81526004016111bd90615172565b6008805460ff191660011790556120903383613007565b611c8757611c8761519a565b6001600160a01b0382163314156120b5576120b561519a565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60085460ff16156121445760405162461bcd60e51b81526004016111bd90615172565b6008805460ff1916600117905561215b3383613007565b6121675761216761519a565b600082815260126020908152604080832081518083019092528054600f0b825260010154918101919091529062093a80806121a28542615129565b6121ac91906150f6565b6121b6919061510a565b9050428260200151116121fa5760405162461bcd60e51b815260206004820152600c60248201526b131bd8dac8195e1c1a5c995960a21b60448201526064016111bd565b60008260000151600f0b136122455760405162461bcd60e51b8152602060048201526011602482015270139bdd1a1a5b99c81a5cc81b1bd8dad959607a1b60448201526064016111bd565b816020015181116122985760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e0060448201526064016111bd565b6122a562eff10042615129565b8111156122f45760405162461bcd60e51b815260206004820152601f60248201527f566f74696e67206c6f636b2063616e206265203236207765656b73206d61780060448201526064016111bd565b61230384600083856003613dfb565b50506008805460ff191690555050565b6003546001600160a01b0316331461233d5760405162461bcd60e51b81526004016111bd90615206565b6019805460ff1916911515919091179055565b61235c84848433612f04565b823b156124f557604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290612395903390889087908790600401615291565b602060405180830381600087803b1580156123af57600080fd5b505af19250505080156123df575060408051601f3d908101601f191682019092526123dc918101906152c4565b60015b612484573d80801561240d576040519150601f19603f3d011682016040523d82523d6000602084013e612412565b606091505b50805161247c5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016111bd565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146124f35760405162461bcd60e51b815260206004820152602660248201527f4552433732313a2045524337323152656365697665722072656a656374656420604482015265746f6b656e7360d01b60648201526084016111bd565b505b50505050565b6001546001600160a01b0316331461251257600080fd5b6000908152601760205260409020805460ff19169055565b612568600060405180604001604052806000600f0b8152602001600081525060405180604001604052806000600f0b8152602001600081525061306d565b565b60195460ff166125b75760405162461bcd60e51b815260206004820152601860248201527744656c65676174696f6e73204e6f7420416c6c6f7765642160401b60448201526064016111bd565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8666125e2610d09565b805160209182012060408051808201825260058152640332e302e360dc1b90840152805180840194909452838101919091527fd7a1ce683065975771bedf401ecab037f4f4c62cc51fefdc8b39dd246ff0343a60608401524660808401523060a0808501919091528151808503909101815260c0840182528051908301207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60e08501526001600160a01b038b1661010085015261012084018a90526101408085018a90528251808603909101815261016085019092528151919092012061190160f01b61018084015261018283018290526101a28301819052909250906000906101c20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015612752573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166127cc5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e7660448201526d616c6964207369676e617475726560901b60648201526084016111bd565b6001600160a01b0381166000908152601c602052604081208054916127f083615141565b9190505589146128555760405162461bcd60e51b815260206004820152602a60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e76604482015269616c6964206e6f6e636560b01b60648201526084016111bd565b874211156128bc5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a2073696760448201526d1b985d1d5c9948195e1c1a5c995960921b60648201526084016111bd565b6128c6818b61381d565b505050505b505050505050565b600062eff10062093a806128e781426150f6565b6128f1919061510a565b6128fb9190615129565b905060005b825181101561114757600062093a8080601260008786815181106129265761292661515c565b602002602001015181526020019081526020016000206001015461294a91906150f6565b612954919061510a565b905082811015612984576129848483815181106129735761297361515c565b602002602001015162eff100612121565b508061298f81615141565b915050612900565b6000818152600960205260409020546060906001600160a01b03166129fe5760405162461bcd60e51b815260206004820152601b60248201527f517565727920666f72206e6f6e6578697374656e7420746f6b656e000000000060448201526064016111bd565b60008281526012602090815260409182902082518084019093528054600f0b835260010154908201526004546001600160a01b031663dd9ec14984612a43814261374b565b6020850151855160405160e086901b6001600160e01b0319168152600481019490945260248401929092526044830152600f0b606482015260840160006040518083038186803b158015612a9657600080fd5b505afa158015612aaa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115a19190810190614fd4565b60006111576000612ee9565b600082815260166020526040902054158015612b09575060008281526017602052604090205460ff16155b612b255760405162461bcd60e51b81526004016111bd906151b0565b80821415612b3257600080fd5b612b3c3383613007565b612b4557600080fd5b612b4f3382613007565b612b5857600080fd5b6000828152601260208181526040808420815180830183528154600f90810b825260019283015482860190815288885295855283872084518086019095528054820b855290920154938301849052805194519095929490910b921115612bc2578260200151612bc8565b83602001515b604080518082018252600080825260208083018281528b835260128252848320935184546001600160801b0319166001600160801b0390911617845551600190930192909255825180840190935280835290820152909150612c2d908790869061306d565b612c368661368a565b6128cb858383866004613dfb565b60085460009060ff1615612c6a5760405162461bcd60e51b81526004016111bd90615172565b6008805460ff19166001179055612c82848484613890565b6008805460ff19169055949350505050565b6003546001600160a01b03163314612cbe5760405162461bcd60e51b81526004016111bd90615206565b600354600280546001600160a01b0319166001600160a01b03909216919091179055565b60006115a1838361374b565b6000818152600d6020526040812054431415612d0c57506000919050565b610f24824261374b565b60085460ff1615612d395760405162461bcd60e51b81526004016111bd90615172565b6008805460ff1916600190811790915560008381526012602090815260409182902082518084019093528054600f0b8352909201549181019190915281612db35760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016111bd565b60008160000151600f0b13612e035760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b60448201526064016111bd565b42816020015111612e265760405162461bcd60e51b81526004016111bd9061524d565b611d3f83836000846000613dfb565b60085461010090046001600160a01b0316331480612e5d57506001546001600160a01b031633145b612e9d5760405162461bcd60e51b81526020600482015260116024820152702737ba1037b63217b7b632102b37ba32b960791b60448201526064016111bd565b600081815260166020526040902054611f73906001615129565b6001546001600160a01b03163314612ece57600080fd5b6000908152601760205260409020805460ff19166001179055565b6001600160a01b03166000908152600a602052604090205490565b600082815260166020526040902054158015612f2f575060008281526017602052604090205460ff16155b612f4b5760405162461bcd60e51b81526004016111bd906151b0565b600854600160a81b900460ff16612f6184612ee9565b1115612f7f5760405162461bcd60e51b81526004016111bd906152e1565b612f898183613007565b612f9257600080fd5b612f9c8483614084565b612fa684836140eb565b612fc1612fb285611895565b612fbb85611895565b8461416c565b612fcb83836144ce565b6000828152600d60205260408082204390555183916001600160a01b03808716929088169160008051602061559c83398151915291a450505050565b600081815260096020908152604080832054600b8352818420546001600160a01b03918216808652600c855283862088841680885295529285205492938085149392909116149060ff16828061305a5750815b806130625750805b979650505050505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152601354600090819087156131d7574287602001511180156130dd575060008760000151600f0b135b156131215786516130f29062eff1009061532b565b600f0b60208087019190915287015161310c9042906151d2565b856020015161311b9190615369565b600f0b85525b42866020015111801561313b575060008660000151600f0b135b1561317f5785516131509062eff1009061532b565b600f0b60208086019190915286015161316a9042906151d2565b84602001516131799190615369565b600f0b84525b602080880151600090815260148252604090205490870151600f9190910b9350156131d7578660200151866020015114156131bc578291506131d7565b602080870151600090815260149091526040902054600f0b91505b60408051608081018252600080825260208201524291810191909152436060820152811561324c575060008181526005602090815260409182902082516080810184528154600f81810b8352600160801b909104900b9281019290925260018101549282019290925260029091015460608201525b60408101518160004283101561329957604084015161326b90426151d2565b606085015161327a90436151d2565b61328c90670de0b6b3a764000061510a565b61329691906150f6565b90505b600062093a806132a981866150f6565b6132b3919061510a565b905060005b60ff81101561342e576132ce62093a8083615129565b91506000428311156132e2574292506132f6565b50600082815260146020526040902054600f0b5b61330086846151d2565b876020015161330f9190615369565b8751889061331e9083906153fe565b600f0b90525060208701805182919061333890839061544e565b600f90810b90915288516000910b1215905061335357600087525b60008760200151600f0b121561336b57600060208801525b60408088018490528501519295508592670de0b6b3a76400009061338f90856151d2565b613399908661510a565b6133a391906150f6565b85606001516133b29190615129565b60608801526133c2600189615129565b9750428314156133d8575043606087015261342e565b6000888152600560209081526040918290208951918a01516001600160801b03908116600160801b02921691909117815590880151600182015560608801516002909101555061342781615141565b90506132b8565b505060138590558b156134b9578860200151886020015161344f91906153fe565b84602001818151613460919061544e565b600f0b9052508851885161347491906153fe565b8451859061348390839061544e565b600f90810b90915260208601516000910b121590506134a457600060208501525b60008460000151600f0b12156134b957600084525b6000858152600560209081526040918290208651918701516001600160801b03908116600160801b02921691909117815590850151600182015560608501516002909101558b1561367c57428b60200151111561357157602089015161351f908861544e565b96508a602001518a60200151141561354357602088015161354090886153fe565b96505b60208b810151600090815260149091526040902080546001600160801b0319166001600160801b0389161790555b428a6020015111156135cc578a602001518a6020015111156135cc57602088015161359c90876153fe565b60208b810151600090815260149091526040902080546001600160801b0319166001600160801b03831617905595505b60008c8152601060205260408120546135e6906001615129565b905080601060008f815260200190815260200160002081905550428960400181815250504389606001818152505088601160008f815260200190815260200160002082633b9aca00811061363c5761363c61515c565b825160208401516001600160801b03908116600160801b029116176003919091029190910190815560408201516001820155606090910151600290910155505b505050505050505050505050565b6136943382613007565b6136e05760405162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656460448201526064016111bd565b6000818152600960205260408120546001600160a01b0316906137039083610f63565b61371761370f82611895565b60008461416c565b61372133836140eb565b60405182906000906001600160a01b0384169060008051602061559c833981519152908390a45050565b60008281526010602052604081205480613769576000915050610f24565b600084815260116020526040812082633b9aca00811061378b5761378b61515c565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b6020830152600181015492820183905260020154606082015291506137d7908561549d565b81602001516137e69190615369565b815182906137f59083906153fe565b600f90810b90915282516000910b1215905061381057600081525b51600f0b9150610f249050565b600061382883611895565b6001600160a01b0384811660008181526018602052604080822080546001600160a01b031916888616908117909155905194955093928516927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a461114783828461454d565b600854600090600160a81b900460ff166138a983612ee9565b11156138c75760405162461bcd60e51b81526004016111bd906152e1565b600062093a80806138d88642615129565b6138e291906150f6565b6138ec919061510a565b9050600085116138fb57600080fd5b4281116139595760405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e207468652060448201526566757475726560d01b60648201526084016111bd565b61396662eff10042615129565b8111156139b55760405162461bcd60e51b815260206004820152601f60248201527f566f74696e67206c6f636b2063616e206265203236207765656b73206d61780060448201526064016111bd565b6007600081546139c490615141565b909155506007546139d58482614909565b5060008181526012602090815260409182902082518084019093528054600f0b835260019081015491830191909152613a1391839189918691613dfb565b95945050505050565b600080839050600062093a80808360400151613a3891906150f6565b613a42919061510a565b905060005b60ff811015613af657613a5d62093a8083615129565b9150600085831115613a7157859250613a85565b50600082815260146020526040902054600f0b5b6040840151613a9490846151d2565b8460200151613aa39190615369565b84518590613ab29083906153fe565b600f0b90525082861415613ac65750613af6565b8084602001818151613ad8919061544e565b600f0b9052505060408301829052613aef81615141565b9050613a47565b5060008260000151600f0b1215613b0c57600082525b50516001600160801b03169392505050565b600043821115613b3057613b3061519a565b600083815260106020526040812054815b6080811015613bd457818310613b5657613bd4565b60006002613b648486615129565b613b6f906001615129565b613b7991906150f6565b6000888152601160205260409020909150869082633b9aca008110613ba057613ba061515c565b600302016002015411613bb557809350613bc3565b613bc06001826151d2565b92505b50613bcd81615141565b9050613b41565b50600085815260116020526040812083633b9aca008110613bf757613bf761515c565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b602083015260018101549282019290925260029091015460608201526013549091506000613c4c8783613ffa565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508084841015613d2b576000600581613cb0876001615129565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060808301829052860151919250613d0d91906151d2565b925083604001518160400151613d2391906151d2565b915050613d4f565b6060830151613d3a90436151d2565b9150826040015142613d4c91906151d2565b90505b60408301518215613d8c578284606001518c613d6b91906151d2565b613d75908461510a565b613d7f91906150f6565b613d899082615129565b90505b6040870151613d9b90826151d2565b8760200151613daa9190615369565b87518890613db99083906153fe565b600f90810b90915288516000910b129050613de957505093516001600160801b03169650610f2495505050505050565b60009950505050505050505050610f24565b6015548290613e0a8682615129565b6015556040805180820190915260008082526020820152825160208085015190830152600f0b8152825187908490613e4390839061544e565b600f0b9052508515613e5757602083018690525b6000888152601260209081526040909120845181546001600160801b0319166001600160801b0390911617815590840151600190910155613e9988828561306d565b338715801590613ebb57506004856004811115613eb857613eb86154dc565b14155b15613f5f576000546040516323b872dd60e01b81526001600160a01b038381166004830152306024830152604482018b905262010000909204909116906323b872dd90606401602060405180830381600087803b158015613f1b57600080fd5b505af1158015613f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f5391906151e9565b613f5f57613f5f61519a565b8360200151816001600160a01b03167fff04ccafc360e16b67d682d17bd9503c4c6b9a131f6be6325762dc9ffc7de6248b8b8942604051613fa394939291906154f2565b60405180910390a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c83613fd78a82615129565b6040805192835260208301919091520160405180910390a1505050505050505050565b60008082815b608081101561407a578183106140155761407a565b600060026140238486615129565b61402e906001615129565b61403891906150f6565b600081815260056020526040902060020154909150871061405b57809350614069565b6140666001826151d2565b92505b5061407381615141565b9050614000565b5090949350505050565b6000818152600960205260409020546001600160a01b038381169116146140ad576140ad61519a565b6000818152600b60205260409020546001600160a01b0316156140e7576000818152600b6020526040902080546001600160a01b03191690555b5050565b6000818152600960205260409020546001600160a01b038381169116146141145761411461519a565b600081815260096020526040902080546001600160a01b031916905561413a8282614968565b6001600160a01b0382166000908152600a602052604081208054600192906141639084906151d2565b90915550505050565b816001600160a01b0316836001600160a01b03161415801561418e5750600081115b15611147576001600160a01b0383161561430f576001600160a01b0383166000908152601b602052604081205463ffffffff1690816141f2576001600160a01b0385166000908152601a602090815260408083208380529091529020600101614234565b6001600160a01b0385166000908152601a6020526040812090614216600185615098565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061424186614a1a565b6001600160a01b0387166000908152601a6020908152604080832063ffffffff8516845290915281209192506001909101905b83548110156142ce5760008482815481106142915761429161515c565b906000526020600020015490508681146142bb578254600181018455600084815260209020018190555b50806142c681615141565b915050614274565b506142da846001615530565b6001600160a01b0388166000908152601b60205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03821615611147576001600160a01b0382166000908152601b602052604081205463ffffffff16908161436e576001600160a01b0384166000908152601a6020908152604080832083805290915290206001016143b0565b6001600160a01b0384166000908152601a6020526040812090614392600185615098565b63ffffffff1663ffffffff1681526020019081526020016000206001015b905060006143bd85614a1a565b6001600160a01b0386166000908152601a6020908152604080832063ffffffff8516845290915290208354919250600190810191610400916143ff9190615129565b111561441d5760405162461bcd60e51b81526004016111bd90615558565b60005b835481101561446f57600084828154811061443d5761443d61515c565b60009182526020808320909101548554600181018755868452919092200155508061446781615141565b915050614420565b50805460018181018355600083815260209020909101869055614493908590615530565b6001600160a01b0387166000908152601b60205260409020805463ffffffff9290921663ffffffff1990921691909117905550505050505050565b6000818152600960205260409020546001600160a01b0316156144f3576144f361519a565b600081815260096020526040902080546001600160a01b0319166001600160a01b0384161790556145248282614a93565b6001600160a01b0382166000908152600a60205260408120805460019290614163908490615129565b806001600160a01b0316826001600160a01b031614611147576001600160a01b03821615614700576001600160a01b0382166000908152601b602052604081205463ffffffff1690816145c5576001600160a01b0384166000908152601a602090815260408083208380529091529020600101614607565b6001600160a01b0384166000908152601a60205260408120906145e9600185615098565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061461485614a1a565b6001600160a01b0386166000908152601a6020908152604080832063ffffffff8516845290915281209192506001909101905b83548110156146bf5760008482815481106146645761466461515c565b600091825260208083209091015480835260099091526040909120549091506001600160a01b03908116908a16146146ac578254600181018455600084815260209020018190555b50806146b781615141565b915050614647565b506146cb846001615530565b6001600160a01b0387166000908152601b60205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03811615611147576001600160a01b0381166000908152601b602052604081205463ffffffff16908161475f576001600160a01b0383166000908152601a6020908152604080832083805290915290206001016147a1565b6001600160a01b0383166000908152601a6020526040812090614783600185615098565b63ffffffff1663ffffffff1681526020019081526020016000206001015b905060006147ae84614a1a565b6001600160a01b038086166000908152601a6020908152604080832063ffffffff861684528252808320938b168352600a9091529020548454929350600190910191610400906147ff908390615129565b111561481d5760405162461bcd60e51b81526004016111bd90615558565b60005b845481101561486f57600085828154811061483d5761483d61515c565b60009182526020808320909101548654600181018855878452919092200155508061486781615141565b915050614820565b5060005b818110156148c1576001600160a01b0389166000908152600e6020908152604080832084845282528220548554600181018755868452919092200155806148b981615141565b915050614873565b506148cd856001615530565b6001600160a01b0387166000908152601b60205260409020805463ffffffff9290921663ffffffff199092169190911790555050505050505050565b60006001600160a01b0383166149215761492161519a565b61492f6000612fbb85611895565b61493983836144ce565b60405182906001600160a01b0385169060009060008051602061559c833981519152908290a450600192915050565b6000600161497584612ee9565b61497f91906151d2565b6000838152600f6020526040902054909150808214156149cf576001600160a01b0384166000908152600e602090815260408083208584528252808320839055858352600f9091528120556124f5565b6001600160a01b03939093166000908152600e6020908152604080832093835292815282822080548684528484208190558352600f9091528282209490945592839055908252812055565b6001600160a01b0381166000908152601b6020526040812054429063ffffffff168015801590614a8357506001600160a01b0384166000908152601a602052604081208391614a6a600185615098565b63ffffffff168152602081019190915260400160002054145b156115a157611a2c600182615098565b6000614a9e83612ee9565b6001600160a01b039093166000908152600e602090815260408083208684528252808320859055938252600f9052919091209190915550565b6001600160e01b03198116811461192d57600080fd5b600060208284031215614aff57600080fd5b81356115a181614ad7565b60005b83811015614b25578181015183820152602001614b0d565b838111156124f55750506000910152565b60008151808452614b4e816020860160208601614b0a565b601f01601f19169290920160200192915050565b6020815260006115a16020830184614b36565b80356001600160a01b0381168114614b8c57600080fd5b919050565b60008060408385031215614ba457600080fd5b614bad83614b75565b946020939093013593505050565b600060208284031215614bcd57600080fd5b5035919050565b600060208284031215614be657600080fd5b6115a182614b75565b60008060408385031215614c0257600080fd5b50508035926020909101359150565b600080600060608486031215614c2657600080fd5b614c2f84614b75565b9250614c3d60208501614b75565b9150604084013590509250925092565b60008060408385031215614c6057600080fd5b614c6983614b75565b9150614c7760208401614b75565b90509250929050565b803560ff81168114614b8c57600080fd5b600060208284031215614ca357600080fd5b6115a182614c80565b6020808252825182820181905260009190848201906040850190845b81811015614ce457835183529284019291840191600101614cc8565b50909695505050505050565b801515811461192d57600080fd5b60008060408385031215614d1157600080fd5b614d1a83614b75565b91506020830135614d2a81614cf0565b809150509250929050565b600060208284031215614d4757600080fd5b81356115a181614cf0565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614d9157614d91614d52565b604052919050565b600067ffffffffffffffff821115614db357614db3614d52565b50601f01601f191660200190565b60008060008060808587031215614dd757600080fd5b614de085614b75565b9350614dee60208601614b75565b925060408501359150606085013567ffffffffffffffff811115614e1157600080fd5b8501601f81018713614e2257600080fd5b8035614e35614e3082614d99565b614d68565b818152886020838501011115614e4a57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060008060008060c08789031215614e8557600080fd5b614e8e87614b75565b95506020870135945060408701359350614eaa60608801614c80565b92506080870135915060a087013590509295509295509295565b60006020808385031215614ed757600080fd5b823567ffffffffffffffff80821115614eef57600080fd5b818501915085601f830112614f0357600080fd5b813581811115614f1557614f15614d52565b8060051b9150614f26848301614d68565b8181529183018401918481019088841115614f4057600080fd5b938501935b83851015614f5e57843582529385019390850190614f45565b98975050505050505050565b600080600060608486031215614f7f57600080fd5b8335925060208401359150614f9660408501614b75565b90509250925092565b60008060408385031215614fb257600080fd5b614fbb83614b75565b9150602083013563ffffffff81168114614d2a57600080fd5b600060208284031215614fe657600080fd5b815167ffffffffffffffff811115614ffd57600080fd5b8201601f8101841361500e57600080fd5b805161501c614e3082614d99565b81815285602083850101111561503157600080fd5b613a13826020830160208601614b0a565b60008251615054818460208701614b0a565b6e0102b37ba34b7339022b9b1b937bb9608d1b920191825250630f09f94960e41b600f820152601301919050565b634e487b7160e01b600052601160045260246000fd5b600063ffffffff838116908316818110156150b5576150b5615082565b039392505050565b634e487b7160e01b600052601260045260246000fd5b600063ffffffff808416806150ea576150ea6150bd565b92169190910492915050565b600082615105576151056150bd565b500490565b600081600019048311821515161561512457615124615082565b500290565b6000821982111561513c5761513c615082565b500190565b600060001982141561515557615155615082565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252600e908201526d4e6f2072652d656e7472616e637960901b604082015260600190565b634e487b7160e01b600052600160045260246000fd5b602080825260089082015267185d1d1858da195960c21b604082015260600190565b6000828210156151e4576151e4615082565b500390565b6000602082840312156151fb57600080fd5b81516115a181614cf0565b602080825260039082015262216d7360e81b604082015260600190565b61766560f01b815260008251615240816002850160208701614b0a565b9190910160020192915050565b60208082526024908201527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686040820152636472617760e01b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611ee690830184614b36565b6000602082840312156152d657600080fd5b81516115a181614ad7565b6020808252602a908201527f45786365656473204d6178204e465420486f6c64696e67204c696d69742070656040820152697220616464726573732160b01b606082015260800190565b600081600f0b83600f0b80615342576153426150bd565b60016001607f1b031982146000198214161561536057615360615082565b90059392505050565b600081600f0b83600f0b60016001607f1b0360008213600084138383048511828216161561539957615399615082565b60016001607f1b031960008512828116878305871216156153bc576153bc615082565b600087129250858205871284841616156153d8576153d8615082565b858505871281841616156153ee576153ee615082565b5050509290910295945050505050565b600081600f0b83600f0b600081128160016001607f1b03190183128115161561542957615429615082565b8160016001607f1b0301831381161561544457615444615082565b5090039392505050565b600081600f0b83600f0b600082128260016001607f1b030382138115161561547857615478615082565b8260016001607f1b031903821281161561549457615494615082565b50019392505050565b60008083128015600160ff1b8501841216156154bb576154bb615082565b6001600160ff1b03840183138116156154d6576154d6615082565b50500390565b634e487b7160e01b600052602160045260246000fd5b84815260208101849052608081016005841061551e57634e487b7160e01b600052602160045260246000fd5b60408201939093526060015292915050565b600063ffffffff80831681851680830382111561554f5761554f615082565b01949350505050565b60208082526023908201527f64737452657020776f756c64206861766520746f6f206d616e7920746f6b656e60408201526249647360e81b60608201526080019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212200aa7da1f62b2de08222c7ea286230a0971031faa83a6b945aadfb7adc37899be64736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104c25760003560e01c80638462151c11610278578063c1f0fb9f1161015c578063e441135c116100ce578063f096636811610092578063f096636814610c6f578063f1127ed814610c7c578063f8a0576314610ca7578063fbd3a29d14610cca578063fc0c546a14610cdd578063fd4a77f114610cf657600080fd5b8063e441135c14610bc6578063e7a324dc14610be6578063e7e242d414610c0d578063e985e9c514610c20578063ee99fe2814610c5c57600080fd5b8063d157e30111610120578063d157e30114610b3f578063d1c2babb14610b47578063d1febfb914610b5a578063d4e54c3b14610b98578063d826f88f14610bab578063e0514aba14610bb357600080fd5b8063c1f0fb9f14610aeb578063c2c4c5c114610afe578063c3cda52014610b06578063c568d48014610b19578063c87b56dd14610b2c57600080fd5b8063986b7d8a116101f5578063a2ee4a7c116101b9578063a2ee4a7c14610a3e578063a4d855df14610a52578063aab8015814610a65578063b45a3c0e14610a78578063b88d4fde14610ac0578063b94ef2b814610ad357600080fd5b8063986b7d8a146109df5780639ab24eb0146109f2578063a0b2d57f14610a05578063a183af5214610a18578063a22cb46514610a2b57600080fd5b8063900cf0cf1161023c578063900cf0cf146109955780639506ec8e1461099e57806395d89b41146109b15780639624d163146109b9578063981b24d0146109cc57600080fd5b80638462151c1461091957806385f2aef2146109395780638c2c9baf1461094c5780638e539e8c1461095f5780638fbb38ff1461097257600080fd5b806342842e0e116103aa57806362af40731161031c57806370a08231116102e057806370a08231146108a05780637116c60c146108b357806371197484146108c65780637d549e99146108e95780637e1c0c09146108f15780637ecebe00146108f957600080fd5b806362af40731461080b5780636352211e1461081e57806365fc3873146108475780636f5488371461085a5780636fcfff451461087a57600080fd5b80634bc2a6571161036e5780634bc2a6571461079257806354fd4d50146107a55780635594a045146107c9578063587cde1e146107dc5780635c19a95c146107ef5780635f5b0c321461080257600080fd5b806342842e0e14610720578063430c208114610733578063461f711c1461074657806346c96aac1461076c578063485cc9551461077f57600080fd5b806318160ddd116104435780632e1a7d4d116104075780632e1a7d4d146106845780632e720f7d146106975780632f745c59146106aa578063313ce567146106e05780633a46b1a8146106fa5780633b1e371f1461070d57600080fd5b806318160ddd146106295780631c984bc31461063157806320606b701461064457806323b872dd1461066b57806325a58b561461067e57600080fd5b8063095cf5c61161048a578063095cf5c61461059e578063095ea7b3146105b35780630d6a2033146105c65780631376f3da146105e657806314a3c8c31461062157600080fd5b806301ffc9a7146104c7578063047fc9aa1461050957806306fdde03146105205780630758c7d814610535578063081812fc1461055d575b600080fd5b6104f46104d5366004614aed565b6001600160e01b03191660009081526006602052604090205460ff1690565b60405190151581526020015b60405180910390f35b61051260155481565b604051908152602001610500565b610528610d09565b6040516105009190614b62565b610548610543366004614b91565b610db9565b60405163ffffffff9091168152602001610500565b61058661056b366004614bbb565b6000908152600b60205260409020546001600160a01b031690565b6040516001600160a01b039091168152602001610500565b6105b16105ac366004614bd4565b610f2a565b005b6105b16105c1366004614b91565b610f63565b6105126105d4366004614bbb565b60166020526000908152604090205481565b6105f96105f4366004614bef565b61104c565b60408051600f95860b81529390940b6020840152928201526060810191909152608001610500565b6105b1611093565b61051261114c565b61051261063f366004614bef565b61115c565b6105127f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6105b1610679366004614c11565b61118e565b43610512565b6105b1610692366004614bbb565b61119a565b6105b16106a5366004614bd4565b611456565b6105126106b8366004614b91565b6001600160a01b03919091166000908152600e60209081526040808320938352929052205490565b6106e8601281565b60405160ff9091168152602001610500565b610512610708366004614b91565b61148f565b6105b161071b366004614bd4565b61152e565b6105b161072e366004614c11565b61157a565b6104f4610741366004614b91565b611595565b610759610754366004614bbb565b6115a8565b604051600f9190910b8152602001610500565b600154610586906001600160a01b031681565b6105b161078d366004614c4d565b6115eb565b6105b16107a0366004614bd4565b61187e565b610528604051806040016040528060058152602001640332e302e360dc1b81525081565b600454610586906001600160a01b031681565b6105866107ea366004614bd4565b611895565b6105b16107fd366004614bd4565b6118c5565b61051261040081565b6105b1610819366004614c91565b611930565b61058661082c366004614bbb565b6000908152600960205260409020546001600160a01b031690565b610512610855366004614bef565b61197a565b610512610868366004614bbb565b600d6020526000908152604090205481565b610548610888366004614bd4565b601b6020526000908152604090205463ffffffff1681565b6105126108ae366004614bd4565b6119c9565b6105126108c1366004614bbb565b6119d4565b6107596108d4366004614bbb565b601460205260009081526040902054600f0b81565b600754610512565b610512611a34565b610512610907366004614bd4565b601c6020526000908152604090205481565b61092c610927366004614bd4565b611a4d565b6040516105009190614cac565b600254610586906001600160a01b031681565b61051261095a366004614bef565b611b0b565b61051261096d366004614bbb565b611b17565b6104f4610980366004614bbb565b60176020526000908152604090205460ff1681565b61051260135481565b6105b16109ac366004614bd4565b611b22565b610528611b74565b6105b16109c7366004614bef565b611c10565b6105126109da366004614bbb565b611d4e565b6105b16109ed366004614bbb565b611ef0565b610512610a00366004614bd4565b611f85565b600354610586906001600160a01b031681565b6105b1610a26366004614bef565b612056565b6105b1610a39366004614cfe565b61209c565b6008546106e890600160a81b900460ff1681565b6105b1610a60366004614bef565b612121565b6105b1610a73366004614d35565b612313565b610aa6610a86366004614bbb565b60126020526000908152604090208054600190910154600f9190910b9082565b60408051600f9390930b8352602083019190915201610500565b6105b1610ace366004614dc1565b612350565b6008546105869061010090046001600160a01b031681565b6105b1610af9366004614bbb565b6124fb565b6105b161252a565b6105b1610b14366004614e6c565b61256a565b6105b1610b27366004614ec4565b6128d3565b610528610b3a366004614bbb565b612997565b610512612ad2565b6105b1610b55366004614bef565b612ade565b6105f9610b68366004614bbb565b600560205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b610512610ba6366004614f6a565b612c44565b6105b1612c94565b610512610bc1366004614bef565b612ce2565b610512610bd4366004614bbb565b60106020526000908152604090205481565b6105127fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b610512610c1b366004614bbb565b612cee565b6104f4610c2e366004614c4d565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b6105b1610c6a366004614bef565b612d16565b6019546104f49060ff1681565b610512610c8a366004614f9f565b601a60209081526000928352604080842090915290825290205481565b610512610cb5366004614bbb565b60009081526012602052604090206001015490565b6105b1610cd8366004614bbb565b612e35565b600054610586906201000090046001600160a01b031681565b6105b1610d04366004614bbb565b612eb7565b6060600060029054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015610d5957600080fd5b505afa158015610d6d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d959190810190614fd4565b604051602001610da59190615042565b604051602081830303815290604052905090565b6001600160a01b0382166000908152601b602052604081205463ffffffff1680610de7576000915050610f24565b6001600160a01b0384166000908152601a602052604081208491610e0c600185615098565b63ffffffff16815260208101919091526040016000205411610e3b57610e33600182615098565b915050610f24565b6001600160a01b0384166000908152601a60209081526040808320838052909152902054831015610e70576000915050610f24565b600080610e7e600184615098565b90505b8163ffffffff168163ffffffff161115610f1f5760006002610ea38484615098565b610ead91906150d3565b610eb79083615098565b6001600160a01b0388166000908152601a6020908152604080832063ffffffff851684529091529020805491925090871415610ef957509350610f2492505050565b8054871115610f0a57819350610f18565b610f15600183615098565b92505b5050610e81565b509150505b92915050565b6002546001600160a01b03163314610f4157600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600960205260409020546001600160a01b031680610f8557600080fd5b806001600160a01b0316836001600160a01b03161415610fa457600080fd5b6000828152600960209081526040808320546001600160a01b038581168552600c845282852033808752945291909320549216149060ff168180610fe55750805b610fee57600080fd5b6000848152600b602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a45050505050565b601160205281600052604060002081633b9aca00811061106b57600080fd5b6003020180546001820154600290920154600f82810b9550600160801b90920490910b925084565b600061109e33612ee9565b9050600062eff10062093a806110b481426150f6565b6110be919061510a565b6110c89190615129565b905060005b8281101561114757336000908152600e60209081526040808320848452825280832054808452601290925282206001015490919062093a80906111119082906150f6565b61111b919061510a565b905083811015611132576111328262eff100612121565b5050808061113f90615141565b9150506110cd565b505050565b6000611157426119d4565b905090565b600082815260116020526040812082633b9aca00811061117e5761117e61515c565b6003020160010154905092915050565b61114783838333612f04565b60085460ff16156111c65760405162461bcd60e51b81526004016111bd90615172565b60405180910390fd5b6008805460ff191660011790556111dd3382613007565b6111e9576111e961519a565b600081815260166020526040902054158015611214575060008181526017602052604090205460ff16155b6112305760405162461bcd60e51b81526004016111bd906151b0565b60008181526012602090815260409182902082518084019093528054600f0b8352600101549082018190524210156112a35760405162461bcd60e51b8152602060048201526016602482015275546865206c6f636b206469646e27742065787069726560501b60448201526064016111bd565b8051604080518082018252600080825260208083018281528783526012909152929020905181546001600160801b0319166001600160801b039091161781559051600190910155601554600f9190910b906112fe82826151d2565b6015556040805180820190915260008082526020820152611322908590859061306d565b60005460405163a9059cbb60e01b815233600482015260248101849052620100009091046001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561137357600080fd5b505af1158015611387573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ab91906151e9565b6113b7576113b761519a565b6113c08461368a565b60408051858152602081018490524281830152905133917f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94919081900360600190a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c8161142e84826151d2565b6040805192835260208301919091520160405180910390a150506008805460ff191690555050565b6002546001600160a01b0316331461146d57600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60008061149c8484610db9565b6001600160a01b0385166000908152601a6020908152604080832063ffffffff851684529091528120919250600190910190805b82548110156115245760008382815481106114ed576114ed61515c565b90600052602060002001549050611504818861374b565b61150e9084615129565b925050808061151c90615141565b9150506114d0565b5095945050505050565b6003546001600160a01b031633146115585760405162461bcd60e51b81526004016111bd90615206565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b61114783838360405180602001604052806000815250612350565b60006115a18383613007565b9392505050565b6000818152601060209081526040808320546011909252822081633b9aca0081106115d5576115d561515c565b6003020154600160801b9004600f0b9392505050565b600054610100900460ff161580801561160b5750600054600160ff909116105b806116255750303b158015611625575060005460ff166001145b6116885760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016111bd565b6000805460ff1916600117905580156116ab576000805461ff0019166101001790555b6000805462010000600160b01b031916620100006001600160a01b038681169190910291909117825560018054336001600160a01b03199182168117835560028054831682179055600380548316909117905560048054909116928616929092179091556008805460ff60a81b1916600560aa1b179055437f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746be55427f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bd5560066020527f477a984de5936bcb02475f64e0ea676103106ac0785c67bf7e9e846450b51ef6805460ff1990811683179091557fd544553a2e70858ffdf1e1169f6f124859d29ddf2686bcabf4e6f71bc63044228054821683179055635b5e139f60e01b83527fcc41b8fe3dd37df8e4a56c49f4e83a8fb6899f1fe8f1ddc40678281e8ec62212805490911690911790556007546040519091309160008051602061559c833981519152908290a4600754604051600090309060008051602061559c833981519152908390a48015611147576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6001546001600160a01b0316331461155857600080fd5b6001600160a01b0380821660009081526018602052604081205490911680156118be57806115a1565b5090919050565b60195460ff166119125760405162461bcd60e51b815260206004820152601860248201527744656c65676174696f6e73204e6f7420416c6c6f7765642160401b60448201526064016111bd565b6001600160a01b0381166119235750335b61192d338261381d565b50565b6003546001600160a01b0316331461195a5760405162461bcd60e51b81526004016111bd90615206565b6008805460ff909216600160a81b0260ff60a81b19909216919091179055565b60085460009060ff16156119a05760405162461bcd60e51b81526004016111bd90615172565b6008805460ff191660011790556119b8838333613890565b6008805460ff191690559392505050565b6000610f2482612ee9565b601354600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060820152909190611a2c8185613a1c565b949350505050565b6000611a406000612ee9565b60075461115791906151d2565b60606000611a5a83612ee9565b905060008167ffffffffffffffff811115611a7757611a77614d52565b604051908082528060200260200182016040528015611aa0578160200160208202803683370190505b50905060005b82811015611b03576001600160a01b0385166000908152600e602090815260408083208484529091529020548251839083908110611ae657611ae661515c565b602090810291909101015280611afb81615141565b915050611aa6565b509392505050565b60006115a18383613b1e565b6000610f24826119d4565b6003546001600160a01b03163314611b4c5760405162461bcd60e51b81526004016111bd90615206565b600880546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6060600060029054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611bc457600080fd5b505afa158015611bd8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c009190810190614fd4565b604051602001610da59190615223565b60085460ff1615611c335760405162461bcd60e51b81526004016111bd90615172565b6008805460ff19166001179055600254336001600160a01b0390911614611c875760405162461bcd60e51b81526020600482015260086024820152676e6f74207465616d60c01b60448201526064016111bd565b60008281526012602090815260409182902082518084019093528054600f0b8352600101549082015281611cbd57611cbd61519a565b60008160000151600f0b13611d0d5760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b60448201526064016111bd565b42816020015111611d305760405162461bcd60e51b81526004016111bd9061524d565b611d3f83836000846002613dfb565b50506008805460ff1916905550565b600043821115611d6057611d6061519a565b6013546000611d6f8483613ffa565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606082015291925083831015611e7e576000600581611dd2866001615129565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905285015191925014611e785782606001518160600151611e3e91906151d2565b83604001518260400151611e5291906151d2565b6060850151611e61908a6151d2565b611e6b919061510a565b611e7591906150f6565b91505b50611ecd565b43826060015114611ecd576060820151611e9890436151d2565b6040830151611ea790426151d2565b6060840151611eb690896151d2565b611ec0919061510a565b611eca91906150f6565b90505b611ee682828460400151611ee19190615129565b613a1c565b9695505050505050565b60085461010090046001600160a01b0316331480611f1857506001546001600160a01b031633145b611f585760405162461bcd60e51b81526020600482015260116024820152702737ba1037b63217b7b632102b37ba32b960791b60448201526064016111bd565b600081815260166020526040902054611f73906001906151d2565b60009182526016602052604090912055565b6001600160a01b0381166000908152601b602052604081205463ffffffff1680611fb25750600092915050565b6001600160a01b0383166000908152601a6020526040812081611fd6600185615098565b63ffffffff1663ffffffff16815260200190815260200160002060010190506000805b825481101561204d5760008382815481106120165761201661515c565b9060005260206000200154905061202d814261374b565b6120379084615129565b925050808061204590615141565b915050611ff9565b50949350505050565b60085460ff16156120795760405162461bcd60e51b81526004016111bd90615172565b6008805460ff191660011790556120903383613007565b611c8757611c8761519a565b6001600160a01b0382163314156120b5576120b561519a565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60085460ff16156121445760405162461bcd60e51b81526004016111bd90615172565b6008805460ff1916600117905561215b3383613007565b6121675761216761519a565b600082815260126020908152604080832081518083019092528054600f0b825260010154918101919091529062093a80806121a28542615129565b6121ac91906150f6565b6121b6919061510a565b9050428260200151116121fa5760405162461bcd60e51b815260206004820152600c60248201526b131bd8dac8195e1c1a5c995960a21b60448201526064016111bd565b60008260000151600f0b136122455760405162461bcd60e51b8152602060048201526011602482015270139bdd1a1a5b99c81a5cc81b1bd8dad959607a1b60448201526064016111bd565b816020015181116122985760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e0060448201526064016111bd565b6122a562eff10042615129565b8111156122f45760405162461bcd60e51b815260206004820152601f60248201527f566f74696e67206c6f636b2063616e206265203236207765656b73206d61780060448201526064016111bd565b61230384600083856003613dfb565b50506008805460ff191690555050565b6003546001600160a01b0316331461233d5760405162461bcd60e51b81526004016111bd90615206565b6019805460ff1916911515919091179055565b61235c84848433612f04565b823b156124f557604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290612395903390889087908790600401615291565b602060405180830381600087803b1580156123af57600080fd5b505af19250505080156123df575060408051601f3d908101601f191682019092526123dc918101906152c4565b60015b612484573d80801561240d576040519150601f19603f3d011682016040523d82523d6000602084013e612412565b606091505b50805161247c5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016111bd565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146124f35760405162461bcd60e51b815260206004820152602660248201527f4552433732313a2045524337323152656365697665722072656a656374656420604482015265746f6b656e7360d01b60648201526084016111bd565b505b50505050565b6001546001600160a01b0316331461251257600080fd5b6000908152601760205260409020805460ff19169055565b612568600060405180604001604052806000600f0b8152602001600081525060405180604001604052806000600f0b8152602001600081525061306d565b565b60195460ff166125b75760405162461bcd60e51b815260206004820152601860248201527744656c65676174696f6e73204e6f7420416c6c6f7765642160401b60448201526064016111bd565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8666125e2610d09565b805160209182012060408051808201825260058152640332e302e360dc1b90840152805180840194909452838101919091527fd7a1ce683065975771bedf401ecab037f4f4c62cc51fefdc8b39dd246ff0343a60608401524660808401523060a0808501919091528151808503909101815260c0840182528051908301207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60e08501526001600160a01b038b1661010085015261012084018a90526101408085018a90528251808603909101815261016085019092528151919092012061190160f01b61018084015261018283018290526101a28301819052909250906000906101c20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015612752573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166127cc5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e7660448201526d616c6964207369676e617475726560901b60648201526084016111bd565b6001600160a01b0381166000908152601c602052604081208054916127f083615141565b9190505589146128555760405162461bcd60e51b815260206004820152602a60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e76604482015269616c6964206e6f6e636560b01b60648201526084016111bd565b874211156128bc5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a2073696760448201526d1b985d1d5c9948195e1c1a5c995960921b60648201526084016111bd565b6128c6818b61381d565b505050505b505050505050565b600062eff10062093a806128e781426150f6565b6128f1919061510a565b6128fb9190615129565b905060005b825181101561114757600062093a8080601260008786815181106129265761292661515c565b602002602001015181526020019081526020016000206001015461294a91906150f6565b612954919061510a565b905082811015612984576129848483815181106129735761297361515c565b602002602001015162eff100612121565b508061298f81615141565b915050612900565b6000818152600960205260409020546060906001600160a01b03166129fe5760405162461bcd60e51b815260206004820152601b60248201527f517565727920666f72206e6f6e6578697374656e7420746f6b656e000000000060448201526064016111bd565b60008281526012602090815260409182902082518084019093528054600f0b835260010154908201526004546001600160a01b031663dd9ec14984612a43814261374b565b6020850151855160405160e086901b6001600160e01b0319168152600481019490945260248401929092526044830152600f0b606482015260840160006040518083038186803b158015612a9657600080fd5b505afa158015612aaa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115a19190810190614fd4565b60006111576000612ee9565b600082815260166020526040902054158015612b09575060008281526017602052604090205460ff16155b612b255760405162461bcd60e51b81526004016111bd906151b0565b80821415612b3257600080fd5b612b3c3383613007565b612b4557600080fd5b612b4f3382613007565b612b5857600080fd5b6000828152601260208181526040808420815180830183528154600f90810b825260019283015482860190815288885295855283872084518086019095528054820b855290920154938301849052805194519095929490910b921115612bc2578260200151612bc8565b83602001515b604080518082018252600080825260208083018281528b835260128252848320935184546001600160801b0319166001600160801b0390911617845551600190930192909255825180840190935280835290820152909150612c2d908790869061306d565b612c368661368a565b6128cb858383866004613dfb565b60085460009060ff1615612c6a5760405162461bcd60e51b81526004016111bd90615172565b6008805460ff19166001179055612c82848484613890565b6008805460ff19169055949350505050565b6003546001600160a01b03163314612cbe5760405162461bcd60e51b81526004016111bd90615206565b600354600280546001600160a01b0319166001600160a01b03909216919091179055565b60006115a1838361374b565b6000818152600d6020526040812054431415612d0c57506000919050565b610f24824261374b565b60085460ff1615612d395760405162461bcd60e51b81526004016111bd90615172565b6008805460ff1916600190811790915560008381526012602090815260409182902082518084019093528054600f0b8352909201549181019190915281612db35760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016111bd565b60008160000151600f0b13612e035760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b60448201526064016111bd565b42816020015111612e265760405162461bcd60e51b81526004016111bd9061524d565b611d3f83836000846000613dfb565b60085461010090046001600160a01b0316331480612e5d57506001546001600160a01b031633145b612e9d5760405162461bcd60e51b81526020600482015260116024820152702737ba1037b63217b7b632102b37ba32b960791b60448201526064016111bd565b600081815260166020526040902054611f73906001615129565b6001546001600160a01b03163314612ece57600080fd5b6000908152601760205260409020805460ff19166001179055565b6001600160a01b03166000908152600a602052604090205490565b600082815260166020526040902054158015612f2f575060008281526017602052604090205460ff16155b612f4b5760405162461bcd60e51b81526004016111bd906151b0565b600854600160a81b900460ff16612f6184612ee9565b1115612f7f5760405162461bcd60e51b81526004016111bd906152e1565b612f898183613007565b612f9257600080fd5b612f9c8483614084565b612fa684836140eb565b612fc1612fb285611895565b612fbb85611895565b8461416c565b612fcb83836144ce565b6000828152600d60205260408082204390555183916001600160a01b03808716929088169160008051602061559c83398151915291a450505050565b600081815260096020908152604080832054600b8352818420546001600160a01b03918216808652600c855283862088841680885295529285205492938085149392909116149060ff16828061305a5750815b806130625750805b979650505050505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152601354600090819087156131d7574287602001511180156130dd575060008760000151600f0b135b156131215786516130f29062eff1009061532b565b600f0b60208087019190915287015161310c9042906151d2565b856020015161311b9190615369565b600f0b85525b42866020015111801561313b575060008660000151600f0b135b1561317f5785516131509062eff1009061532b565b600f0b60208086019190915286015161316a9042906151d2565b84602001516131799190615369565b600f0b84525b602080880151600090815260148252604090205490870151600f9190910b9350156131d7578660200151866020015114156131bc578291506131d7565b602080870151600090815260149091526040902054600f0b91505b60408051608081018252600080825260208201524291810191909152436060820152811561324c575060008181526005602090815260409182902082516080810184528154600f81810b8352600160801b909104900b9281019290925260018101549282019290925260029091015460608201525b60408101518160004283101561329957604084015161326b90426151d2565b606085015161327a90436151d2565b61328c90670de0b6b3a764000061510a565b61329691906150f6565b90505b600062093a806132a981866150f6565b6132b3919061510a565b905060005b60ff81101561342e576132ce62093a8083615129565b91506000428311156132e2574292506132f6565b50600082815260146020526040902054600f0b5b61330086846151d2565b876020015161330f9190615369565b8751889061331e9083906153fe565b600f0b90525060208701805182919061333890839061544e565b600f90810b90915288516000910b1215905061335357600087525b60008760200151600f0b121561336b57600060208801525b60408088018490528501519295508592670de0b6b3a76400009061338f90856151d2565b613399908661510a565b6133a391906150f6565b85606001516133b29190615129565b60608801526133c2600189615129565b9750428314156133d8575043606087015261342e565b6000888152600560209081526040918290208951918a01516001600160801b03908116600160801b02921691909117815590880151600182015560608801516002909101555061342781615141565b90506132b8565b505060138590558b156134b9578860200151886020015161344f91906153fe565b84602001818151613460919061544e565b600f0b9052508851885161347491906153fe565b8451859061348390839061544e565b600f90810b90915260208601516000910b121590506134a457600060208501525b60008460000151600f0b12156134b957600084525b6000858152600560209081526040918290208651918701516001600160801b03908116600160801b02921691909117815590850151600182015560608501516002909101558b1561367c57428b60200151111561357157602089015161351f908861544e565b96508a602001518a60200151141561354357602088015161354090886153fe565b96505b60208b810151600090815260149091526040902080546001600160801b0319166001600160801b0389161790555b428a6020015111156135cc578a602001518a6020015111156135cc57602088015161359c90876153fe565b60208b810151600090815260149091526040902080546001600160801b0319166001600160801b03831617905595505b60008c8152601060205260408120546135e6906001615129565b905080601060008f815260200190815260200160002081905550428960400181815250504389606001818152505088601160008f815260200190815260200160002082633b9aca00811061363c5761363c61515c565b825160208401516001600160801b03908116600160801b029116176003919091029190910190815560408201516001820155606090910151600290910155505b505050505050505050505050565b6136943382613007565b6136e05760405162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656460448201526064016111bd565b6000818152600960205260408120546001600160a01b0316906137039083610f63565b61371761370f82611895565b60008461416c565b61372133836140eb565b60405182906000906001600160a01b0384169060008051602061559c833981519152908390a45050565b60008281526010602052604081205480613769576000915050610f24565b600084815260116020526040812082633b9aca00811061378b5761378b61515c565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b6020830152600181015492820183905260020154606082015291506137d7908561549d565b81602001516137e69190615369565b815182906137f59083906153fe565b600f90810b90915282516000910b1215905061381057600081525b51600f0b9150610f249050565b600061382883611895565b6001600160a01b0384811660008181526018602052604080822080546001600160a01b031916888616908117909155905194955093928516927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a461114783828461454d565b600854600090600160a81b900460ff166138a983612ee9565b11156138c75760405162461bcd60e51b81526004016111bd906152e1565b600062093a80806138d88642615129565b6138e291906150f6565b6138ec919061510a565b9050600085116138fb57600080fd5b4281116139595760405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e207468652060448201526566757475726560d01b60648201526084016111bd565b61396662eff10042615129565b8111156139b55760405162461bcd60e51b815260206004820152601f60248201527f566f74696e67206c6f636b2063616e206265203236207765656b73206d61780060448201526064016111bd565b6007600081546139c490615141565b909155506007546139d58482614909565b5060008181526012602090815260409182902082518084019093528054600f0b835260019081015491830191909152613a1391839189918691613dfb565b95945050505050565b600080839050600062093a80808360400151613a3891906150f6565b613a42919061510a565b905060005b60ff811015613af657613a5d62093a8083615129565b9150600085831115613a7157859250613a85565b50600082815260146020526040902054600f0b5b6040840151613a9490846151d2565b8460200151613aa39190615369565b84518590613ab29083906153fe565b600f0b90525082861415613ac65750613af6565b8084602001818151613ad8919061544e565b600f0b9052505060408301829052613aef81615141565b9050613a47565b5060008260000151600f0b1215613b0c57600082525b50516001600160801b03169392505050565b600043821115613b3057613b3061519a565b600083815260106020526040812054815b6080811015613bd457818310613b5657613bd4565b60006002613b648486615129565b613b6f906001615129565b613b7991906150f6565b6000888152601160205260409020909150869082633b9aca008110613ba057613ba061515c565b600302016002015411613bb557809350613bc3565b613bc06001826151d2565b92505b50613bcd81615141565b9050613b41565b50600085815260116020526040812083633b9aca008110613bf757613bf761515c565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b602083015260018101549282019290925260029091015460608201526013549091506000613c4c8783613ffa565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508084841015613d2b576000600581613cb0876001615129565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060808301829052860151919250613d0d91906151d2565b925083604001518160400151613d2391906151d2565b915050613d4f565b6060830151613d3a90436151d2565b9150826040015142613d4c91906151d2565b90505b60408301518215613d8c578284606001518c613d6b91906151d2565b613d75908461510a565b613d7f91906150f6565b613d899082615129565b90505b6040870151613d9b90826151d2565b8760200151613daa9190615369565b87518890613db99083906153fe565b600f90810b90915288516000910b129050613de957505093516001600160801b03169650610f2495505050505050565b60009950505050505050505050610f24565b6015548290613e0a8682615129565b6015556040805180820190915260008082526020820152825160208085015190830152600f0b8152825187908490613e4390839061544e565b600f0b9052508515613e5757602083018690525b6000888152601260209081526040909120845181546001600160801b0319166001600160801b0390911617815590840151600190910155613e9988828561306d565b338715801590613ebb57506004856004811115613eb857613eb86154dc565b14155b15613f5f576000546040516323b872dd60e01b81526001600160a01b038381166004830152306024830152604482018b905262010000909204909116906323b872dd90606401602060405180830381600087803b158015613f1b57600080fd5b505af1158015613f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f5391906151e9565b613f5f57613f5f61519a565b8360200151816001600160a01b03167fff04ccafc360e16b67d682d17bd9503c4c6b9a131f6be6325762dc9ffc7de6248b8b8942604051613fa394939291906154f2565b60405180910390a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c83613fd78a82615129565b6040805192835260208301919091520160405180910390a1505050505050505050565b60008082815b608081101561407a578183106140155761407a565b600060026140238486615129565b61402e906001615129565b61403891906150f6565b600081815260056020526040902060020154909150871061405b57809350614069565b6140666001826151d2565b92505b5061407381615141565b9050614000565b5090949350505050565b6000818152600960205260409020546001600160a01b038381169116146140ad576140ad61519a565b6000818152600b60205260409020546001600160a01b0316156140e7576000818152600b6020526040902080546001600160a01b03191690555b5050565b6000818152600960205260409020546001600160a01b038381169116146141145761411461519a565b600081815260096020526040902080546001600160a01b031916905561413a8282614968565b6001600160a01b0382166000908152600a602052604081208054600192906141639084906151d2565b90915550505050565b816001600160a01b0316836001600160a01b03161415801561418e5750600081115b15611147576001600160a01b0383161561430f576001600160a01b0383166000908152601b602052604081205463ffffffff1690816141f2576001600160a01b0385166000908152601a602090815260408083208380529091529020600101614234565b6001600160a01b0385166000908152601a6020526040812090614216600185615098565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061424186614a1a565b6001600160a01b0387166000908152601a6020908152604080832063ffffffff8516845290915281209192506001909101905b83548110156142ce5760008482815481106142915761429161515c565b906000526020600020015490508681146142bb578254600181018455600084815260209020018190555b50806142c681615141565b915050614274565b506142da846001615530565b6001600160a01b0388166000908152601b60205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03821615611147576001600160a01b0382166000908152601b602052604081205463ffffffff16908161436e576001600160a01b0384166000908152601a6020908152604080832083805290915290206001016143b0565b6001600160a01b0384166000908152601a6020526040812090614392600185615098565b63ffffffff1663ffffffff1681526020019081526020016000206001015b905060006143bd85614a1a565b6001600160a01b0386166000908152601a6020908152604080832063ffffffff8516845290915290208354919250600190810191610400916143ff9190615129565b111561441d5760405162461bcd60e51b81526004016111bd90615558565b60005b835481101561446f57600084828154811061443d5761443d61515c565b60009182526020808320909101548554600181018755868452919092200155508061446781615141565b915050614420565b50805460018181018355600083815260209020909101869055614493908590615530565b6001600160a01b0387166000908152601b60205260409020805463ffffffff9290921663ffffffff1990921691909117905550505050505050565b6000818152600960205260409020546001600160a01b0316156144f3576144f361519a565b600081815260096020526040902080546001600160a01b0319166001600160a01b0384161790556145248282614a93565b6001600160a01b0382166000908152600a60205260408120805460019290614163908490615129565b806001600160a01b0316826001600160a01b031614611147576001600160a01b03821615614700576001600160a01b0382166000908152601b602052604081205463ffffffff1690816145c5576001600160a01b0384166000908152601a602090815260408083208380529091529020600101614607565b6001600160a01b0384166000908152601a60205260408120906145e9600185615098565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061461485614a1a565b6001600160a01b0386166000908152601a6020908152604080832063ffffffff8516845290915281209192506001909101905b83548110156146bf5760008482815481106146645761466461515c565b600091825260208083209091015480835260099091526040909120549091506001600160a01b03908116908a16146146ac578254600181018455600084815260209020018190555b50806146b781615141565b915050614647565b506146cb846001615530565b6001600160a01b0387166000908152601b60205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03811615611147576001600160a01b0381166000908152601b602052604081205463ffffffff16908161475f576001600160a01b0383166000908152601a6020908152604080832083805290915290206001016147a1565b6001600160a01b0383166000908152601a6020526040812090614783600185615098565b63ffffffff1663ffffffff1681526020019081526020016000206001015b905060006147ae84614a1a565b6001600160a01b038086166000908152601a6020908152604080832063ffffffff861684528252808320938b168352600a9091529020548454929350600190910191610400906147ff908390615129565b111561481d5760405162461bcd60e51b81526004016111bd90615558565b60005b845481101561486f57600085828154811061483d5761483d61515c565b60009182526020808320909101548654600181018855878452919092200155508061486781615141565b915050614820565b5060005b818110156148c1576001600160a01b0389166000908152600e6020908152604080832084845282528220548554600181018755868452919092200155806148b981615141565b915050614873565b506148cd856001615530565b6001600160a01b0387166000908152601b60205260409020805463ffffffff9290921663ffffffff199092169190911790555050505050505050565b60006001600160a01b0383166149215761492161519a565b61492f6000612fbb85611895565b61493983836144ce565b60405182906001600160a01b0385169060009060008051602061559c833981519152908290a450600192915050565b6000600161497584612ee9565b61497f91906151d2565b6000838152600f6020526040902054909150808214156149cf576001600160a01b0384166000908152600e602090815260408083208584528252808320839055858352600f9091528120556124f5565b6001600160a01b03939093166000908152600e6020908152604080832093835292815282822080548684528484208190558352600f9091528282209490945592839055908252812055565b6001600160a01b0381166000908152601b6020526040812054429063ffffffff168015801590614a8357506001600160a01b0384166000908152601a602052604081208391614a6a600185615098565b63ffffffff168152602081019190915260400160002054145b156115a157611a2c600182615098565b6000614a9e83612ee9565b6001600160a01b039093166000908152600e602090815260408083208684528252808320859055938252600f9052919091209190915550565b6001600160e01b03198116811461192d57600080fd5b600060208284031215614aff57600080fd5b81356115a181614ad7565b60005b83811015614b25578181015183820152602001614b0d565b838111156124f55750506000910152565b60008151808452614b4e816020860160208601614b0a565b601f01601f19169290920160200192915050565b6020815260006115a16020830184614b36565b80356001600160a01b0381168114614b8c57600080fd5b919050565b60008060408385031215614ba457600080fd5b614bad83614b75565b946020939093013593505050565b600060208284031215614bcd57600080fd5b5035919050565b600060208284031215614be657600080fd5b6115a182614b75565b60008060408385031215614c0257600080fd5b50508035926020909101359150565b600080600060608486031215614c2657600080fd5b614c2f84614b75565b9250614c3d60208501614b75565b9150604084013590509250925092565b60008060408385031215614c6057600080fd5b614c6983614b75565b9150614c7760208401614b75565b90509250929050565b803560ff81168114614b8c57600080fd5b600060208284031215614ca357600080fd5b6115a182614c80565b6020808252825182820181905260009190848201906040850190845b81811015614ce457835183529284019291840191600101614cc8565b50909695505050505050565b801515811461192d57600080fd5b60008060408385031215614d1157600080fd5b614d1a83614b75565b91506020830135614d2a81614cf0565b809150509250929050565b600060208284031215614d4757600080fd5b81356115a181614cf0565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614d9157614d91614d52565b604052919050565b600067ffffffffffffffff821115614db357614db3614d52565b50601f01601f191660200190565b60008060008060808587031215614dd757600080fd5b614de085614b75565b9350614dee60208601614b75565b925060408501359150606085013567ffffffffffffffff811115614e1157600080fd5b8501601f81018713614e2257600080fd5b8035614e35614e3082614d99565b614d68565b818152886020838501011115614e4a57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060008060008060c08789031215614e8557600080fd5b614e8e87614b75565b95506020870135945060408701359350614eaa60608801614c80565b92506080870135915060a087013590509295509295509295565b60006020808385031215614ed757600080fd5b823567ffffffffffffffff80821115614eef57600080fd5b818501915085601f830112614f0357600080fd5b813581811115614f1557614f15614d52565b8060051b9150614f26848301614d68565b8181529183018401918481019088841115614f4057600080fd5b938501935b83851015614f5e57843582529385019390850190614f45565b98975050505050505050565b600080600060608486031215614f7f57600080fd5b8335925060208401359150614f9660408501614b75565b90509250925092565b60008060408385031215614fb257600080fd5b614fbb83614b75565b9150602083013563ffffffff81168114614d2a57600080fd5b600060208284031215614fe657600080fd5b815167ffffffffffffffff811115614ffd57600080fd5b8201601f8101841361500e57600080fd5b805161501c614e3082614d99565b81815285602083850101111561503157600080fd5b613a13826020830160208601614b0a565b60008251615054818460208701614b0a565b6e0102b37ba34b7339022b9b1b937bb9608d1b920191825250630f09f94960e41b600f820152601301919050565b634e487b7160e01b600052601160045260246000fd5b600063ffffffff838116908316818110156150b5576150b5615082565b039392505050565b634e487b7160e01b600052601260045260246000fd5b600063ffffffff808416806150ea576150ea6150bd565b92169190910492915050565b600082615105576151056150bd565b500490565b600081600019048311821515161561512457615124615082565b500290565b6000821982111561513c5761513c615082565b500190565b600060001982141561515557615155615082565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252600e908201526d4e6f2072652d656e7472616e637960901b604082015260600190565b634e487b7160e01b600052600160045260246000fd5b602080825260089082015267185d1d1858da195960c21b604082015260600190565b6000828210156151e4576151e4615082565b500390565b6000602082840312156151fb57600080fd5b81516115a181614cf0565b602080825260039082015262216d7360e81b604082015260600190565b61766560f01b815260008251615240816002850160208701614b0a565b9190910160020192915050565b60208082526024908201527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686040820152636472617760e01b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611ee690830184614b36565b6000602082840312156152d657600080fd5b81516115a181614ad7565b6020808252602a908201527f45786365656473204d6178204e465420486f6c64696e67204c696d69742070656040820152697220616464726573732160b01b606082015260800190565b600081600f0b83600f0b80615342576153426150bd565b60016001607f1b031982146000198214161561536057615360615082565b90059392505050565b600081600f0b83600f0b60016001607f1b0360008213600084138383048511828216161561539957615399615082565b60016001607f1b031960008512828116878305871216156153bc576153bc615082565b600087129250858205871284841616156153d8576153d8615082565b858505871281841616156153ee576153ee615082565b5050509290910295945050505050565b600081600f0b83600f0b600081128160016001607f1b03190183128115161561542957615429615082565b8160016001607f1b0301831381161561544457615444615082565b5090039392505050565b600081600f0b83600f0b600082128260016001607f1b030382138115161561547857615478615082565b8260016001607f1b031903821281161561549457615494615082565b50019392505050565b60008083128015600160ff1b8501841216156154bb576154bb615082565b6001600160ff1b03840183138116156154d6576154d6615082565b50500390565b634e487b7160e01b600052602160045260246000fd5b84815260208101849052608081016005841061551e57634e487b7160e01b600052602160045260246000fd5b60408201939093526060015292915050565b600063ffffffff80831681851680830382111561554f5761554f615082565b01949350505050565b60208082526023908201527f64737452657020776f756c64206861766520746f6f206d616e7920746f6b656e60408201526249647360e81b60608201526080019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212200aa7da1f62b2de08222c7ea286230a0971031faa83a6b945aadfb7adc37899be64736f6c63430008090033
Deployed Bytecode Sourcemap
28309:60093:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45535:136;;;;;;:::i;:::-;-1:-1:-1;;;;;;45630:33:0;45606:4;45630:33;;;:19;:33;;;;;;;;;45535:136;;;;565:14:1;;558:22;540:41;;528:2;513:18;45535:136:0;;;;;;;;50735:18;;;;;;;;;738:25:1;;;726:2;711:18;50735::0;592:177:1;32555:155:0;;;:::i;:::-;;;;;;;:::i;78166:1064::-;;;;;;:::i;:::-;;:::i;:::-;;;2136:10:1;2124:23;;;2106:42;;2094:2;2079:18;78166:1064:0;1962:192:1;35835:117:0;;;;;;:::i;:::-;35894:7;35921:23;;;:13;:23;;;;;;-1:-1:-1;;;;;35921:23:0;;35835:117;;;;-1:-1:-1;;;;;2508:32:1;;;2490:51;;2478:2;2463:18;35835:117:0;2344:203:1;33048:110:0;;;;;;:::i;:::-;;:::i;:::-;;37056:658;;;;;;:::i;:::-;;:::i;74248:40::-;;;;;;:::i;:::-;;;;;;;;;;;;;;50482: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;50482:60:0;2996:419:1;64827:370:0;;;:::i;72907:109::-;;;:::i;51729:150::-;;;;;;:::i;:::-;;:::i;76108:122::-;;76150:80;76108:122;;41921:174;;;;;;:::i;:::-;;:::i;60022:91::-;60093:12;60022:91;;65309:977;;;;;;:::i;:::-;;:::i;33166:120::-;;;;;;:::i;:::-;;:::i;46167:159::-;;;;;;:::i;:::-;-1:-1:-1;;;;;46277:28:0;;;;46253:4;46277:28;;;:20;:28;;;;;;;;:41;;;;;;;;;46167:159;32513:35;;32546:2;32513:35;;;;;4107:4:1;4095:17;;;4077:36;;4065:2;4050:18;32513:35:0;3935:184:1;79238:582:0;;;;;;:::i;:::-;;:::i;88011:114::-;;;;;;:::i;:::-;;:::i;42826:173::-;;;;;;:::i;:::-;;:::i;39775:153::-;;;;;;:::i;:::-;;:::i;51328:194::-;;;;;;:::i;:::-;;:::i;:::-;;;4297:2:1;4286:22;;;;4268:41;;4256:2;4241:18;51328:194:0;4124:191:1;29919:20:0;;;;;-1:-1:-1;;;;;29919:20:0;;;31208:727;;;;;;:::i;:::-;;:::i;74338:115::-;;;;;;:::i;:::-;;:::i;32466:40::-;;;;;;;;;;;;;;;-1:-1:-1;;;32466:40:0;;;;;29996:23;;;;;-1:-1:-1;;;;;29996:23:0;;;77271:187;;;;;;:::i;:::-;;:::i;85586:230::-;;;;;;:::i;:::-;;:::i;76555:41::-;;76592:4;76555:41;;88133:122;;;;;;:::i;:::-;;:::i;34381:107::-;;;;;;:::i;:::-;34434:7;34461:19;;;:9;:19;;;;;;-1:-1:-1;;;;;34461:19:0;;34381:107;62337:166;;;;;;:::i;:::-;;:::i;35659:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;76885:48;;;;;;:::i;:::-;;;;;;;;;;;;;;;;35088:106;;;;;;:::i;:::-;;:::i;73190:198::-;;;;;;:::i;:::-;;:::i;50653:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;73554:90;73628:7;;73554:90;;73438:108;;;:::i;77014:38::-;;;;;;:::i;:::-;;;;;;;;;;;;;;73762:287;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;29946:19::-;;;;;-1:-1:-1;;;;;29946:19:0;;;70637:140;;;;;;:::i;:::-;;:::i;79828:127::-;;;;;;:::i;:::-;;:::i;74295:34::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;50629:17;;;;;;87884:119;;;;;;:::i;:::-;;:::i;32716:132::-;;;:::i;87269:502::-;;;;;;:::i;:::-;;:::i;70973:880::-;;;;;;:::i;:::-;;:::i;74921:194::-;;;;;;:::i;:::-;;:::i;77659:499::-;;;;;;:::i;:::-;;:::i;29972:17::-;;;;;-1:-1:-1;;;;;29972:17:0;;;63127:507;;;;;;:::i;:::-;;:::i;38226:301::-;;;;;;:::i;:::-;;:::i;30757:25::-;;;;;-1:-1:-1;;;30757:25:0;;;;;;63770:728;;;;;;:::i;:::-;;:::i;88263:134::-;;;;;;:::i;:::-;;:::i;50578:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6460:2:1;6449:22;;;;6431:41;;6503:2;6488:18;;6481:34;;;;6404:18;50578:44:0;6259:262:1;44208:1020:0;;;;;;:::i;:::-;;:::i;30725:23::-;;;;;;;;-1:-1:-1;;;;;30725:23:0;;;74589:122;;;;;;:::i;:::-;;:::i;60171:106::-;;;:::i;85824:1265::-;;;;;;:::i;:::-;;:::i;64506:313::-;;;;;;:::i;:::-;;:::i;33395:431::-;;;;;;:::i;:::-;;:::i;73652:102::-;;;:::i;75123:722::-;;;;;;:::i;:::-;;:::i;30028:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;30028:43:0;;;;;;;;;62771:176;;;;;;:::i;:::-;;:::i;87779:97::-;;;:::i;68499:130::-;;;;;;:::i;:::-;;:::i;50430:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;76324:117;;76370:71;76324:117;;68292:199;;;;;;:::i;:::-;;:::i;36161:153::-;;;;;;:::i;:::-;-1:-1:-1;;;;;36270:24:0;;;36245:4;36270:24;;;:16;:24;;;;;;;;36269:37;;;;;;;;;;;;;;;36161:153;60602:455;;;;;;:::i;:::-;;:::i;76625:30::-;;;;;;;;;76748:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;52028:111;;;;;;:::i;:::-;52087:4;52111:16;;;:6;:16;;;;;:20;;;;52028:111;74719:194;;;;;;:::i;:::-;;:::i;29892:20::-;;;;;;;;-1:-1:-1;;;;;29892:20:0;;;74461:120;;;;;;:::i;:::-;;:::i;32555:155::-;32591:13;32655:5;;;;;;;;;-1:-1:-1;;;;;32655:5:0;-1:-1:-1;;;;;32648:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32648:20:0;;;;;;;;;;;;:::i;:::-;32631:70;;;;;;;;:::i;:::-;;;;;;;;;;;;;32617:85;;32555:155;:::o;78166:1064::-;-1:-1:-1;;;;;78288:23:0;;78247:6;78288:23;;;:14;:23;;;;;;;;78326:17;78322:58;;78367:1;78360:8;;;;;78322:58;-1:-1:-1;;;;;78438:20:0;;;;;;:11;:20;;;;;78490:9;;78459:16;78474:1;78459:12;:16;:::i;:::-;78438:38;;;;;;;;;;;;;-1:-1:-1;78438:38:0;:48;:61;78434:119;;78524:16;78539:1;78524:12;:16;:::i;:::-;78516:25;;;;;78434:119;-1:-1:-1;;;;;78614:20:0;;;;;;:11;:20;;;;;;;;:23;;;;;;;;:33;:45;-1:-1:-1;78610:86:0;;;78683:1;78676:8;;;;;78610:86;78708:12;;78750:16;78765:1;78750:12;:16;:::i;:::-;78735:31;;78777:423;78792:5;78784:13;;:5;:13;;;78777:423;;;78814:13;78856:1;78839:13;78847:5;78839;:13;:::i;:::-;78838:19;;;;:::i;:::-;78830:27;;:5;:27;:::i;:::-;-1:-1:-1;;;;;78923:20:0;;78899:21;78923:20;;;:11;:20;;;;;;;;:28;;;;;;;;;;78970:12;;78814:43;;-1:-1:-1;78923:28:0;78970:25;;78966:223;;;-1:-1:-1;79023:6:0;-1:-1:-1;79016:13:0;;-1:-1:-1;;;79016:13:0;78966:223;79055:12;;:24;-1:-1:-1;79051:138:0;;;79108:6;79100:14;;79051:138;;;79163:10;79172:1;79163:6;:10;:::i;:::-;79155:18;;79051:138;78799:401;;78777:423;;;-1:-1:-1;79217:5:0;-1:-1:-1;;78166:1064:0;;;;;:::o;33048:110::-;33122:4;;-1:-1:-1;;;;;33122:4:0;33108:10;:18;33100:27;;;;;;33138:4;:12;;-1:-1:-1;;;;;;33138:12:0;-1:-1:-1;;;;;33138:12:0;;;;;;;;;;33048:110::o;37056:658::-;37125:13;37141:19;;;:9;:19;;;;;;-1:-1:-1;;;;;37141:19:0;37231;37223:28;;;;;;37338:5;-1:-1:-1;;;;;37325:18:0;:9;-1:-1:-1;;;;;37325:18:0;;;37317:27;;;;;;37386:18;37408:19;;;:9;:19;;;;;;;;;-1:-1:-1;;;;;37484:23:0;;;;;:16;:23;;;;;37431:10;37483:37;;;;;;;;;;37408:19;;:33;;37483:37;;37408:33;;37539:39;;;37556:22;37539:39;37531:48;;;;;;37619:23;;;;:13;:23;;;;;;:35;;-1:-1:-1;;;;;;37619:35:0;-1:-1:-1;;;;;37619:35:0;;;;;;;;;37670:36;;37619:23;;37670:36;;;;;;;37114:600;;;37056:658;;:::o;50482:60::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;50482:60:0;;;;;;;-1:-1:-1;50482:60:0;:::o;64827:370::-;64863:9;64875:20;64884:10;64875:8;:20::i;:::-;64863:32;-1:-1:-1;64903:9:0;50839:14;50792:7;64915:22;50792:7;64915:15;:22;:::i;:::-;:29;;;;:::i;:::-;:39;;;;:::i;:::-;64903:51;;64966:6;64962:228;64976:4;64974:1;:6;64962:228;;;65029:10;64996:9;65008:32;;;:20;:32;;;;;;;;:35;;;;;;;;;65064:12;;;:6;:12;;;;;:16;;;65008:35;;64996:9;50792:7;;65064:23;;50792:7;;65064:23;:::i;:::-;:30;;;;:::i;:::-;65052:42;;65114:4;65107;:11;65104:78;;;65133:38;65155:4;50839:14;65133:20;:38::i;:::-;64987:203;;64982:3;;;;;:::i;:::-;;;;64962:228;;;;64858:339;;64827:370::o;72907:109::-;72953:4;72977:31;72992:15;72977:14;:31::i;:::-;72970:38;;72907:109;:::o;51729:150::-;51810:4;51834:28;;;:18;:28;;;;;51863:4;51834:34;;;;;;;:::i;:::-;;;;:37;;;51827:44;;51729:150;;;;:::o;41921:174::-;42040:47;42054:5;42061:3;42066:8;42076:10;42040:13;:47::i;65309:977::-;32172:7;;;;32171:8;32163:35;;;;-1:-1:-1;;;32163:35:0;;;;;;;:::i;:::-;;;;;;;;;32209:7;:14;;-1:-1:-1;;32209:14:0;32219:4;32209:14;;;65382:40:::1;65401:10;65413:8:::0;65382:18:::1;:40::i;:::-;65375:48;;;;:::i;:::-;65442:21;::::0;;;:11:::1;:21;::::0;;;;;:26;:46;::::1;;;-1:-1:-1::0;65473:15:0::1;::::0;;;:5:::1;:15;::::0;;;;;::::1;;65472:16;65442:46;65434:67;;;;-1:-1:-1::0;;;65434:67:0::1;;;;;;;:::i;:::-;65514:29;65546:16:::0;;;:6:::1;:16;::::0;;;;;;;;65514:48;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;65581:15:::1;:31;;65573:66;;;::::0;-1:-1:-1;;;65573:66:0;;13846:2:1;65573:66:0::1;::::0;::::1;13828:21:1::0;13885:2;13865:18;;;13858:30;-1:-1:-1;;;13904:18:1;;;13897:52;13966:18;;65573:66:0::1;13644:346:1::0;65573:66:0::1;65675:15:::0;;65724:18:::1;::::0;;;;::::1;::::0;;-1:-1:-1;65724:18:0;;;::::1;::::0;;::::1;::::0;;;65705:16;;;:6:::1;:16:::0;;;;;;:37;;;;-1:-1:-1;;;;;;65705:37:0::1;-1:-1:-1::0;;;;;65705:37:0;;;::::1;::::0;;;;-1:-1:-1;65705:37:0;;::::1;::::0;65774:6:::1;::::0;65668:23:::1;::::0;;;::::1;::::0;65800:21:::1;65668:23:::0;65774:6;65800:21:::1;:::i;:::-;65791:6;:30:::0;66012:18:::1;::::0;;;;::::1;::::0;;;-1:-1:-1;66012:18:0;;;::::1;::::0;::::1;::::0;65980:51:::1;::::0;65992:8;;66002;;65980:11:::1;:51::i;:::-;66058:5;::::0;66051:41:::1;::::0;-1:-1:-1;;;66051:41:0;;66074:10:::1;66051:41;::::0;::::1;14299:51:1::0;14366:18;;;14359:34;;;66058:5:0;;;::::1;-1:-1:-1::0;;;;;66058:5:0::1;::::0;66051:22:::1;::::0;14272:18:1;;66051:41:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66044:49;;;;:::i;:::-;66131:15;66137:8;66131:5;:15::i;:::-;66164:54;::::0;;14856:25:1;;;14912:2;14897:18;;14890:34;;;66202:15:0::1;14940:18:1::0;;;14933:34;66164:54:0;;66173:10:::1;::::0;66164:54:::1;::::0;;;;;14844:2:1;66164:54:0;;::::1;66234:44;66241:13:::0;66256:21:::1;66272:5:::0;66241:13;66256:21:::1;:::i;:::-;66234:44;::::0;;15152:25:1;;;15208:2;15193:18;;15186:34;;;;15125:18;66234:44:0::1;;;;;;;-1:-1:-1::0;;32246:7:0;:15;;-1:-1:-1;;32246:15:0;;;-1:-1:-1;;65309:977:0:o;33166:120::-;33245:4;;-1:-1:-1;;;;;33245:4:0;33231:10;:18;33223:27;;;;;;33261:8;:17;;-1:-1:-1;;;;;;33261:17:0;-1:-1:-1;;;;;33261:17:0;;;;;;;;;;33166:120::o;79238:582::-;79341:4;79363:18;79384:37;79402:7;79411:9;79384:17;:37::i;:::-;-1:-1:-1;;;;;79481:20:0;;79454:24;79481:20;;;:11;:20;;;;;;;;:33;;;;;;;;;;79363:58;;-1:-1:-1;79481:42:0;;;;;79454:24;79559:231;79580:16;;79576:20;;79559:231;;;79618:8;79629:9;79639:1;79629:12;;;;;;;;:::i;:::-;;;;;;;;;79618:23;;79749:29;79763:3;79768:9;79749:13;:29::i;:::-;79741:37;;:5;:37;:::i;:::-;79733:45;;79603:187;79598:3;;;;;:::i;:::-;;;;79559:231;;;-1:-1:-1;79807:5:0;79238:582;-1:-1:-1;;;;;79238:582:0:o;88011:114::-;88086:2;;-1:-1:-1;;;;;88086:2:0;88072:10;:16;88064:32;;;;-1:-1:-1;;;88064:32:0;;;;;;;:::i;:::-;88107:5;:10;;-1:-1:-1;;;;;;88107:10:0;-1:-1:-1;;;;;88107:10:0;;;;;;;;;;88011:114::o;42826:173::-;42949:42;42966:5;42973:3;42978:8;42949:42;;;;;;;;;;;;:16;:42::i;39775:153::-;39858:4;39882:38;39901:8;39911;39882:18;:38::i;:::-;39875:45;39775:153;-1:-1:-1;;;39775:153:0:o;51328:194::-;51395:6;51428:26;;;:16;:26;;;;;;;;;51472:18;:28;;;;;51428:26;51472:36;;;;;;;:::i;:::-;;;;:42;-1:-1:-1;;;51472:42:0;;;;;51328:194;-1:-1:-1;;;51328:194:0:o;31208:727::-;25261:19;25284:13;;;;;;25283:14;;25331:34;;;;-1:-1:-1;25349:12:0;;25364:1;25349:12;;;;:16;25331:34;25330:108;;;-1:-1:-1;25410:4:0;16023:19;:23;;;25371:66;;-1:-1:-1;25420:12:0;;;;;:17;25371:66;25308:204;;;;-1:-1:-1;;;25308:204:0;;15764:2:1;25308:204:0;;;15746:21:1;15803:2;15783:18;;;15776:30;15842:34;15822:18;;;15815:62;-1:-1:-1;;;15893:18:1;;;15886:44;15947:19;;25308:204:0;15562:410:1;25308:204:0;25523:12;:16;;-1:-1:-1;;25523:16:0;25538:1;25523:16;;;25550:67;;;;25585:13;:20;;-1:-1:-1;;25585:20:0;;;;;25550:67;31322:5:::1;:18:::0;;-1:-1:-1;;;;;;31322:18:0::1;::::0;-1:-1:-1;;;;;31322:18:0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;31351:18:0;;31359:10:::1;-1:-1:-1::0;;;;;;31351:18:0;;::::1;::::0;::::1;::::0;;31322:5:::1;31380:17:::0;;;::::1;::::0;::::1;::::0;;31408:2:::1;:15:::0;;;::::1;::::0;;::::1;::::0;;31434:8:::1;:20:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;31465:12:::1;:17:::0;;-1:-1:-1;;;;31465:17:0::1;-1:-1:-1::0;;;31465:17:0::1;::::0;;31518:12:::1;31495:20:::0;:35;31563:15:::1;31541:19:::0;:37;31591:19:::1;31495:16;31591:40:::0;;:47;;-1:-1:-1;;31591:47:0;;::::1;::::0;::::1;::::0;;;31649:40;:47;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;31707:49:0;;;:56;;;;::::1;::::0;;::::1;::::0;;31838:7:::1;::::0;31495:16;31802:44;31838:7;;31831:4:::1;::::0;-1:-1:-1;;;;;;;;;;;31802:44:0;31322:5;;31802:44:::1;31919:7;::::0;31883:44:::1;::::0;31915:1:::1;::::0;31900:4:::1;::::0;-1:-1:-1;;;;;;;;;;;31883:44:0;31915:1;;31883:44:::1;25643:14:::0;25639:102;;;25690:5;25674:21;;-1:-1:-1;;25674:21:0;;;25715:14;;-1:-1:-1;4077:36:1;;25715:14:0;;4065:2:1;4050:18;25715:14:0;;;;;;;25250:498;31208:727;;:::o;74338:115::-;74414:5;;-1:-1:-1;;;;;74414:5:0;74400:10;:19;74392:28;;;;;77271:187;-1:-1:-1;;;;;77368:21:0;;;77330:7;77368:21;;;:10;:21;;;;;;77330:7;;77368:21;77407;;:43;;77443:7;77407:43;;;-1:-1:-1;77431:9:0;;77400:50;-1:-1:-1;77271:187:0:o;85586:230::-;85649:18;;;;85641:55;;;;-1:-1:-1;;;85641:55:0;;16378:2:1;85641:55:0;;;16360:21:1;16417:2;16397:18;;;16390:30;-1:-1:-1;;;16436:18:1;;;16429:54;16500:18;;85641:55:0;16176:348:1;85641:55:0;-1:-1:-1;;;;;85711:23:0;;85707:51;;-1:-1:-1;85748:10:0;85707:51;85776:32;85786:10;85798:9;85776;:32::i;:::-;85586:230;:::o;88133:122::-;88209:2;;-1:-1:-1;;;;;88209:2:0;88195:10;:16;88187:32;;;;-1:-1:-1;;;88187:32:0;;;;;;;:::i;:::-;88230:12;:17;;;;;;-1:-1:-1;;;88230:17:0;-1:-1:-1;;;;88230:17:0;;;;;;;;;88133:122::o;62337:166::-;32172:7;;62423:4;;32172:7;;32171:8;32163:35;;;;-1:-1:-1;;;32163:35:0;;;;;;;:::i;:::-;32209:7;:14;;-1:-1:-1;;32209:14:0;32219:4;32209:14;;;62447:48:::1;62460:6:::0;62468:14;62484:10:::1;62447:12;:48::i;:::-;32246:7:::0;:15;;-1:-1:-1;;32246:15:0;;;62440:55;62337:166;-1:-1:-1;;;62337:166:0:o;35088:106::-;35146:4;35170:16;35179:6;35170:8;:16::i;73190:198::-;73274:5;;73243:4;73316:21;;;:13;:21;;;;;;;;73290:47;;;;;;;;;;;;;;;-1:-1:-1;;;73290:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73243:4;;73274:5;73355:25;73290:47;73378:1;73355:10;:25::i;:::-;73348:32;73190:198;-1:-1:-1;;;;73190:198:0:o;73438:108::-;73482:4;73516:20;73533:1;73516:8;:20::i;:::-;73506:7;;:30;;;;:::i;73762:287::-;73820:13;73846:10;73859:14;73868:4;73859:8;:14::i;:::-;73846:27;;73884:17;73915:5;73904:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;73904:17:0;;73884:37;;73936:6;73932:89;73945:5;73943:1;:7;73932:89;;;-1:-1:-1;;;;;73980:26:0;;;;;;:20;:26;;;;;;;;:29;;;;;;;;;73971:6;;:3;;74007:1;;73971:6;;;;;;:::i;:::-;;;;;;;;;;:38;73951:3;;;;:::i;:::-;;;;73932:89;;;-1:-1:-1;74038:3:0;73762:287;-1:-1:-1;;;73762:287:0:o;70637:140::-;70712:4;70736:33;70752:8;70762:6;70736:15;:33::i;79828:127::-;79898:4;79922:25;79937:9;79922:14;:25::i;87884:119::-;87960:2;;-1:-1:-1;;;;;87960:2:0;87946:10;:16;87938:32;;;;-1:-1:-1;;;87938:32:0;;;;;;;:::i;:::-;87981:8;:14;;-1:-1:-1;;;;;87981:14:0;;;;;-1:-1:-1;;;;;;87981:14:0;;;;;;;;;87884:119::o;32716:132::-;32754:13;32823:5;;;;;;;;;-1:-1:-1;;;;;32823:5:0;-1:-1:-1;;;;;32816:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32816:22:0;;;;;;;;;;;;:::i;:::-;32794:45;;;;;;;;:::i;87269:502::-;32172:7;;;;32171:8;32163:35;;;;-1:-1:-1;;;32163:35:0;;;;;;;:::i;:::-;32209:7;:14;;-1:-1:-1;;32209:14:0;32219:4;32209:14;;;87381:4:::1;::::0;87367:10:::1;-1:-1:-1::0;;;;;87381:4:0;;::::1;87367:18;87359:39;;;::::0;-1:-1:-1;;;87359:39:0;;17155:2:1;87359:39:0::1;::::0;::::1;17137:21:1::0;17194:1;17174:18;;;17167:29;-1:-1:-1;;;17212:18:1;;;17205:38;17260:18;;87359:39:0::1;16953:331:1::0;87359:39:0::1;87411:29;87443:16:::0;;;:6:::1;:16;::::0;;;;;;;;87411:48;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;87479:10;87472:18:::1;;;;:::i;:::-;87555:1;87537:8;:15;;;:19;;;87529:54;;;::::0;-1:-1:-1;;;87529:54:0;;17491:2:1;87529:54:0::1;::::0;::::1;17473:21:1::0;17530:2;17510:18;;;17503:30;-1:-1:-1;;;17549:18:1;;;17542:52;17611:18;;87529:54:0::1;17289:346:1::0;87529:54:0::1;87617:15;87602:8;:12;;;:30;87594:79;;;;-1:-1:-1::0;;;87594:79:0::1;;;;;;;:::i;:::-;87686:77;87699:8;87709:6;87717:1;87720:8;87730:32;87686:12;:77::i;:::-;-1:-1:-1::0;;32246:7:0;:15;;-1:-1:-1;;32246:15:0;;;-1:-1:-1;87269:502:0:o;70973:880::-;71032:4;71066:12;71056:6;:22;;71049:30;;;;:::i;:::-;71104:5;;71090:11;71140:33;71158:6;71104:5;71140:17;:33::i;:::-;71186:18;71207:27;;;:13;:27;;;;;;;;71186:48;;;;;;;;;;;;;;;-1:-1:-1;;;71186:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71120:53;;-1:-1:-1;71271:21:0;;;71267:465;;;71309:23;71335:13;71309:23;71349:16;:12;71364:1;71349:16;:::i;:::-;71335:31;;;;;;;;;;;;;;-1:-1:-1;71335:31:0;71309:57;;;;;;;;;;;;;;;-1:-1:-1;;;71309:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71385:9;;;71309:57;;-1:-1:-1;71385:27:0;71381:155;;71510:5;:9;;;71493:10;:14;;;:26;;;;:::i;:::-;71479:5;:8;;;71463:10;:13;;;:24;;;;:::i;:::-;71449:9;;;;71440:18;;:6;:18;:::i;:::-;71439:49;;;;:::i;:::-;71438:82;;;;:::i;:::-;71433:87;;71381:155;71294:253;71267:465;;;71585:12;71572:5;:9;;;:25;71568:153;;71695:9;;;;71680:24;;:12;:24;:::i;:::-;71666:8;;;;71648:26;;:15;:26;:::i;:::-;71634:9;;;;71625:18;;:6;:18;:::i;:::-;71624:51;;;;:::i;:::-;71623:82;;;;:::i;:::-;71618:87;;71568:153;71813:32;71824:5;71842:2;71831:5;:8;;;:13;;;;:::i;:::-;71813:10;:32::i;:::-;71806:39;70973:880;-1:-1:-1;;;;;;70973:880:0:o;74921:194::-;74994:8;;;;;-1:-1:-1;;;;;74994:8:0;74980:10;:22;;:45;;-1:-1:-1;75020:5:0;;-1:-1:-1;;;;;75020:5:0;75006:10;:19;74980:45;74972:75;;;;-1:-1:-1;;;74972:75:0;;18247:2:1;74972:75:0;;;18229:21:1;18286:2;18266:18;;;18259:30;-1:-1:-1;;;18305:18:1;;;18298:47;18362:18;;74972:75:0;18045:341:1;74972:75:0;75082:21;;;;:11;:21;;;;;;:25;;75106:1;;75082:25;:::i;:::-;75058:21;;;;:11;:21;;;;;;:49;74921:194::o;77659:499::-;-1:-1:-1;;;;;77756:23:0;;77717:4;77756:23;;;:14;:23;;;;;;;;77794:17;77790:58;;-1:-1:-1;77835:1:0;;77659:499;-1:-1:-1;;77659:499:0:o;77790:58::-;-1:-1:-1;;;;;77885:20:0;;77858:24;77885:20;;;:11;:20;;;;;77858:24;77906:16;77921:1;77906:12;:16;:::i;:::-;77885:38;;;;;;;;;;;;;;;:47;;77858:74;;77943:10;77973:6;77968:160;77989:16;;77985:20;;77968:160;;;78027:8;78038:9;78048:1;78038:12;;;;;;;;:::i;:::-;;;;;;;;;78027:23;;78081:35;78095:3;78100:15;78081:13;:35::i;:::-;78073:43;;:5;:43;:::i;:::-;78065:51;;78012:116;78007:3;;;;;:::i;:::-;;;;77968:160;;;-1:-1:-1;78145:5:0;77659:499;-1:-1:-1;;;;77659:499:0:o;63127:507::-;32172:7;;;;32171:8;32163:35;;;;-1:-1:-1;;;32163:35:0;;;;;;;:::i;:::-;32209:7;:14;;-1:-1:-1;;32209:14:0;32219:4;32209:14;;;63220:40:::1;63239:10;63251:8:::0;63220:18:::1;:40::i;:::-;63213:48;;;;:::i;38226:301::-:0;-1:-1:-1;;;;;38369:23:0;;38382:10;38369:23;;38362:31;;;;:::i;:::-;38421:10;38404:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;38404:39:0;;;;;;;;;;;;:51;;-1:-1:-1;;38404:51:0;;;;;;;;;;38471:48;;540:41:1;;;38404:39:0;;38421:10;38471:48;;513:18:1;38471:48:0;;;;;;;38226:301;;:::o;63770:728::-;32172:7;;;;32171:8;32163:35;;;;-1:-1:-1;;;32163:35:0;;;;;;;:::i;:::-;32209:7;:14;;-1:-1:-1;;32209:14:0;32219:4;32209:14;;;63874:40:::1;63893:10;63905:8:::0;63874:18:::1;:40::i;:::-;63867:48;;;;:::i;:::-;63928:29;63960:16:::0;;;:6:::1;:16;::::0;;;;;;;63928:48;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;;;50792:7:::1;::::0;64007:32:::1;64025:14:::0;64007:15:::1;:32;:::i;:::-;64006:41;;;;:::i;:::-;:48;;;;:::i;:::-;63987:67;;64127:15;64112:8;:12;;;:30;64104:55;;;::::0;-1:-1:-1;;;64104:55:0;;18593:2:1;64104:55:0::1;::::0;::::1;18575:21:1::0;18632:2;18612:18;;;18605:30;-1:-1:-1;;;18651:18:1;;;18644:42;18703:18;;64104:55:0::1;18391:336:1::0;64104:55:0::1;64196:1;64178:8;:15;;;:19;;;64170:49;;;::::0;-1:-1:-1;;;64170:49:0;;18934:2:1;64170:49:0::1;::::0;::::1;18916:21:1::0;18973:2;18953:18;;;18946:30;-1:-1:-1;;;18992:18:1;;;18985:47;19049:18;;64170:49:0::1;18732:341:1::0;64170:49:0::1;64252:8;:12;;;64238:11;:26;64230:70;;;::::0;-1:-1:-1;;;64230:70:0;;19280:2:1;64230:70:0::1;::::0;::::1;19262:21:1::0;19319:2;19299:18;;;19292:30;19358:33;19338:18;;;19331:61;19409:18;;64230:70:0::1;19078:355:1::0;64230:70:0::1;64334:25;50839:14;64334:15;:25;:::i;:::-;64319:11;:40;;64311:84;;;::::0;-1:-1:-1;;;64311:84:0;;19640:2:1;64311:84:0::1;::::0;::::1;19622:21:1::0;19679:2;19659:18;;;19652:30;19718:33;19698:18;;;19691:61;19769:18;;64311:84:0::1;19438:355:1::0;64311:84:0::1;64408:82;64421:8;64431:1;64434:11;64447:8;64457:32;64408:12;:82::i;:::-;-1:-1:-1::0;;32246:7:0;:15;;-1:-1:-1;;32246:15:0;;;-1:-1:-1;;63770:728:0:o;88263:134::-;88345:2;;-1:-1:-1;;;;;88345:2:0;88331:10;:16;88323:32;;;;-1:-1:-1;;;88323:32:0;;;;;;;:::i;:::-;88366:18;:23;;-1:-1:-1;;88366:23:0;;;;;;;;;;88263:134::o;44208:1020::-;44358:47;44372:5;44379:3;44384:8;44394:10;44358:13;:47::i;:::-;43326:20;;43374:8;44418:803;;44564:84;;-1:-1:-1;;;44564:84:0;;-1:-1:-1;;;;;44564:48:0;;;;;:84;;44613:10;;44625:5;;44632:8;;44642:5;;44564:84;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44564:84:0;;;;;;;;-1:-1:-1;;44564:84:0;;;;;;;;;;;;:::i;:::-;;;44560:650;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44927:13:0;;44923:272;;44970:60;;-1:-1:-1;;;44970:60:0;;20748:2:1;44970:60:0;;;20730:21:1;20787:2;20767:18;;;20760:30;20826:34;20806:18;;;20799:62;-1:-1:-1;;;20877:18:1;;;20870:48;20935:19;;44970:60:0;20546:414:1;44923:272:0;45145:6;45139:13;45130:6;45126:2;45122:15;45115:38;44560:650;-1:-1:-1;;;;;;44698:69:0;;-1:-1:-1;;;44698:69:0;44694:166;;44792:48;;-1:-1:-1;;;44792:48:0;;21167:2:1;44792:48:0;;;21149:21:1;21206:2;21186:18;;;21179:30;21245:34;21225:18;;;21218:62;-1:-1:-1;;;21296:18:1;;;21289:36;21342:19;;44792:48:0;20965:402:1;44694:166:0;44649:226;44560:650;44208:1020;;;;:::o;74589:122::-;74663:5;;-1:-1:-1;;;;;74663:5:0;74649:10;:19;74641:28;;;;;;74698:5;74680:15;;;:5;:15;;;;;:23;;-1:-1:-1;;74680:23:0;;;74589:122::o;60171:106::-;60213:56;60225:1;60228:19;;;;;;;;60242:1;60228:19;;;;;;60245:1;60228:19;;;60249;;;;;;;;60263:1;60249:19;;;;;;60266:1;60249:19;;;60213:11;:56::i;:::-;60171:106::o;85824:1265::-;86009:18;;;;86001:55;;;;-1:-1:-1;;;86001:55:0;;16378:2:1;86001:55:0;;;16360:21:1;16417:2;16397:18;;;16390:30;-1:-1:-1;;;16436:18:1;;;16429:54;16500:18;;86001:55:0;16176:348:1;86001:55:0;86067:23;76150:80;86196:6;:4;:6::i;:::-;86180:24;;;;;;;86239:7;;;;;;;;;;;-1:-1:-1;;;86239:7:0;;;;86117:210;;;;;21631:25:1;;;;21672:18;;;21665:34;;;;86223:25:0;21715:18:1;;;21708:34;86267:13:0;21758:18:1;;;21751:34;86307:4:0;21801:19:1;;;;21794:61;;;;86117:210:0;;;;;;;;;;21603:19:1;;;86117:210:0;;86093:245;;;;;;76370:71;86394:57;;;22097:25:1;-1:-1:-1;;;;;22158:32:1;;22138:18;;;22131:60;22207:18;;;22200:34;;;22250:18;;;;22243:34;;;86394:57:0;;;;;;;;;;22069:19:1;;;86394:57:0;;;86370:92;;;;;;;-1:-1:-1;;;86514:57:0;;;22546:27:1;22589:11;;;22582:27;;;22625:12;;;22618:28;;;86093:245:0;;-1:-1:-1;86370:92:0;-1:-1:-1;;22662:12:1;;86514:57:0;;;-1:-1:-1;;86514:57:0;;;;;;;;;86490:92;;86514:57;86490:92;;;;86593:17;86613:26;;;;;;;;;22912:25:1;;;22985:4;22973:17;;22953:18;;;22946:45;;;;23007:18;;;23000:34;;;23050:18;;;23043:34;;;86490:92:0;;-1:-1:-1;86593:17:0;86613:26;;22884:19:1;;86613:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;86613:26:0;;-1:-1:-1;;86613:26:0;;;-1:-1:-1;;;;;;;86672:23:0;;86650:119;;;;-1:-1:-1;;;86650:119:0;;23290:2:1;86650:119:0;;;23272:21:1;23329:2;23309:18;;;23302:30;23368:34;23348:18;;;23341:62;-1:-1:-1;;;23419:18:1;;;23412:44;23473:19;;86650:119:0;23088:410:1;86650:119:0;-1:-1:-1;;;;;86811:17:0;;;;;;:6;:17;;;;;:19;;;;;;:::i;:::-;;;;;86802:5;:28;86780:120;;;;-1:-1:-1;;;86780:120:0;;23705:2:1;86780:120:0;;;23687:21:1;23744:2;23724:18;;;23717:30;23783:34;23763:18;;;23756:62;-1:-1:-1;;;23834:18:1;;;23827:40;23884:19;;86780:120:0;23503:406:1;86780:120:0;86952:6;86933:15;:25;;86911:121;;;;-1:-1:-1;;;86911:121:0;;24116:2:1;86911:121:0;;;24098:21:1;24155:2;24135:18;;;24128:30;24194:34;24174:18;;;24167:62;-1:-1:-1;;;24245:18:1;;;24238:44;24299:19;;86911:121:0;23914:410:1;86911:121:0;87050:31;87060:9;87071;87050;:31::i;:::-;87043:38;;;;85824:1265;;;;;;;:::o;64506:313::-;64568:9;50839:14;50792:7;64580:22;50792:7;64580:15;:22;:::i;:::-;:29;;;;:::i;:::-;:39;;;;:::i;:::-;64568:51;;64631:6;64627:185;64641:4;:11;64639:1;:13;64627:185;;;64668:9;50792:7;;64680:6;:15;64687:4;64692:1;64687:7;;;;;;;;:::i;:::-;;;;;;;64680:15;;;;;;;;;;;:19;;;:26;;;;:::i;:::-;:33;;;;:::i;:::-;64668:45;;64733:4;64726;:11;64723:81;;;64752:41;64774:4;64779:1;64774:7;;;;;;;;:::i;:::-;;;;;;;50839:14;64752:20;:41::i;:::-;-1:-1:-1;64654:3:0;;;;:::i;:::-;;;;64627:185;;33395:431;33516:1;33485:19;;;:9;:19;;;;;;33451:13;;-1:-1:-1;;;;;33485:19:0;33477:73;;;;-1:-1:-1;;;33477:73:0;;24531:2:1;33477:73:0;;;24513:21:1;24570:2;24550:18;;;24543:30;24609:29;24589:18;;;24582:57;24656:18;;33477:73:0;24329:351:1;33477:73:0;33561:29;33593:16;;;:6;:16;;;;;;;;;33561:48;;;;;;;;;;;;;;;;;;;;;33639:8;;-1:-1:-1;;;;;33639:8:0;33627:31;33600:8;33696:40;33600:8;33720:15;33696:13;:40::i;:::-;33751:12;;;;33790:15;;33627:191;;;;;;-1:-1:-1;;;;;;33627:191:0;;;;;;24916:25:1;;;;24957:18;;;24950:34;;;;25000:18;;;24993:34;33783:23:0;;25043:18:1;;;25036:34;24888:19;;33627:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;33627:191:0;;;;;;;;;;;;:::i;73652:102::-;73702:4;73726:20;73743:1;73726:8;:20::i;75123:722::-;75188:18;;;;:11;:18;;;;;;:23;:40;;;;-1:-1:-1;75216:12:0;;;;:5;:12;;;;;;;;75215:13;75188:40;75180:61;;;;-1:-1:-1;;;75180:61:0;;;;;;;:::i;:::-;75269:3;75260:5;:12;;75252:21;;;;;;75292:37;75311:10;75323:5;75292:18;:37::i;:::-;75284:46;;;;;;75349:35;75368:10;75380:3;75349:18;:35::i;:::-;75341:44;;;;;;75398:29;75430:13;;;:6;:13;;;;;;;;75398:45;;;;;;;;;;;;;;;;;;;;;;;;;;75486:11;;;;;;;;;75454:43;;;;;;;;;;;;;;;;;;;;;;;;75534:15;;75573:12;;75398:45;;75454:43;;75527:23;;;;-1:-1:-1;75573:28:0;:58;;75619:8;:12;;;75573:58;;;75604:8;:12;;;75573:58;75660:19;;;;;;;;-1:-1:-1;75660:19:0;;;;;;;;;;75644:13;;;:6;:13;;;;;:35;;;;-1:-1:-1;;;;;;75644:35:0;-1:-1:-1;;;;;75644:35:0;;;;;;;-1:-1:-1;75644:35:0;;;;;;;75719:19;;;;;;;;;;;;;;;75562:69;;-1:-1:-1;75690:49:0;;75644:13;;75709:8;;75690:11;:49::i;:::-;75750:12;75756:5;75750;:12::i;:::-;75773:64;75786:3;75791:6;75799:3;75804:8;75814:22;75773:12;:64::i;62771:176::-;32172:7;;62874:4;;32172:7;;32171:8;32163:35;;;;-1:-1:-1;;;32163:35:0;;;;;;;:::i;:::-;32209:7;:14;;-1:-1:-1;;32209:14:0;32219:4;32209:14;;;62898:41:::1;62911:6:::0;62919:14;62935:3;62898:12:::1;:41::i;:::-;32246:7:::0;:15;;-1:-1:-1;;32246:15:0;;;62891:48;62771:176;-1:-1:-1;;;;62771:176:0:o;87779:97::-;87838:2;;-1:-1:-1;;;;;87838:2:0;87824:10;:16;87816:32;;;;-1:-1:-1;;;87816:32:0;;;;;;;:::i;:::-;87866:2;;87859:4;:9;;-1:-1:-1;;;;;;87859:9:0;-1:-1:-1;;;;;87866:2:0;;;87859:9;;;;;;87779:97::o;68499:130::-;68570:4;68594:27;68608:8;68618:2;68594:13;:27::i;68292:199::-;68352:4;68373:26;;;:16;:26;;;;;;68403:12;68373:42;68369:56;;;-1:-1:-1;68424:1:0;;68292:199;-1:-1:-1;68292:199:0:o;68369:56::-;68443:40;68457:8;68467:15;68443:13;:40::i;60602:455::-;32172:7;;;;32171:8;32163:35;;;;-1:-1:-1;;;32163:35:0;;;;;;;:::i;:::-;32209:7;:14;;-1:-1:-1;;32209:14:0;32219:4;32209:14;;;;;;:7;60716:16;;;:6:::1;:16;::::0;;;;;;;;60684:48;;;;::::1;::::0;;;;;::::1;;::::0;;;;::::1;::::0;;;::::1;::::0;;;;60753:10;60745:37:::1;;;::::0;-1:-1:-1;;;60745:37:0;;25283:2:1;60745:37:0::1;::::0;::::1;25265:21:1::0;25322:2;25302:18;;;25295:30;-1:-1:-1;;;25341:18:1;;;25334:44;25395:18;;60745:37:0::1;25081:338:1::0;60745:37:0::1;60847:1;60829:8;:15;;;:19;;;60821:54;;;::::0;-1:-1:-1;;;60821:54:0;;17491:2:1;60821:54:0::1;::::0;::::1;17473:21:1::0;17530:2;17510:18;;;17503:30;-1:-1:-1;;;17549:18:1;;;17542:52;17611:18;;60821:54:0::1;17289:346:1::0;60821:54:0::1;60909:15;60894:8;:12;;;:30;60886:79;;;;-1:-1:-1::0;;;60886:79:0::1;;;;;;;:::i;:::-;60976:73;60989:8;60999:6;61007:1;61010:8;61020:28;60976:12;:73::i;74719:194::-:0;74792:8;;;;;-1:-1:-1;;;;;74792:8:0;74778:10;:22;;:45;;-1:-1:-1;74818:5:0;;-1:-1:-1;;;;;74818:5:0;74804:10;:19;74778:45;74770:75;;;;-1:-1:-1;;;74770:75:0;;18247:2:1;74770:75:0;;;18229:21:1;18286:2;18266:18;;;18259:30;-1:-1:-1;;;18305:18:1;;;18298:47;18362:18;;74770:75:0;18045:341:1;74770:75:0;74880:21;;;;:11;:21;;;;;;:25;;74904:1;74880:25;:::i;74461:120::-;74534:5;;-1:-1:-1;;;;;74534:5:0;74520:10;:19;74512:28;;;;;;74551:15;;;;:5;:15;;;;;:22;;-1:-1:-1;;74551:22:0;74569:4;74551:22;;;74461:120::o;34730:116::-;-1:-1:-1;;;;;34811:27:0;34787:4;34811:27;;;:19;:27;;;;;;;34730:116::o;40352:989::-;40506:21;;;;:11;:21;;;;;;:26;:46;;;;-1:-1:-1;40537:15:0;;;;:5;:15;;;;;;;;40536:16;40506:46;40498:67;;;;-1:-1:-1;;;40498:67:0;;;;;;;:::i;:::-;40633:12;;-1:-1:-1;;;40633:12:0;;;;40616:13;40625:3;40616:8;:13::i;:::-;:29;;40607:86;;;;-1:-1:-1;;;40607:86:0;;;;;;;:::i;:::-;40712:37;40731:7;40740:8;40712:18;:37::i;:::-;40704:46;;;;;;40832:31;40847:5;40854:8;40832:14;:31::i;:::-;40938:33;40955:5;40962:8;40938:16;:33::i;:::-;41011:63;41031:16;41041:5;41031:9;:16::i;:::-;41049:14;41059:3;41049:9;:14::i;:::-;41065:8;41011:19;:63::i;:::-;41105:26;41117:3;41122:8;41105:11;:26::i;:::-;41217;;;;:16;:26;;;;;;41246:12;41217:41;;41303:30;41234:8;;-1:-1:-1;;;;;41303:30:0;;;;;;;;-1:-1:-1;;;;;;;;;;;41303:30:0;;40352:989;;;;:::o;39345:422::-;39429:4;39462:19;;;:9;:19;;;;;;;;;39579:13;:23;;;;;;-1:-1:-1;;;;;39462:19:0;;;39645:23;;;:16;:23;;;;;39514:17;;;39644:35;;;;;;;;;39462:19;;39514:17;;;;39579:23;;;;39567:35;;39644;;39514:17;;39697:35;;;39715:17;39697:35;:62;;;;39736:23;39697:62;39690:69;39345:422;-1:-1:-1;;;;;;;39345:422:0:o;52425:5883::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52717:5:0;;52639:17;;;;52739:13;;52735:1170;;52881:15;52864:10;:14;;;:32;:57;;;;;52920:1;52900:10;:17;;;:21;;;52864:57;52860:234;;;52956:17;;:28;;50896:14;;52956:28;:::i;:::-;52942:42;;:11;;;;:42;;;;53044:14;;;:32;;53061:15;;53044:32;:::i;:::-;53016:5;:11;;;:62;;;;:::i;:::-;53003:75;;;;52860:234;53129:15;53112:10;:14;;;:32;:57;;;;;53168:1;53148:10;:17;;;:21;;;53112:57;53108:234;;;53204:17;;:28;;50896:14;;53204:28;:::i;:::-;53190:42;;:11;;;;:42;;;;53292:14;;;:32;;53309:15;;53292:32;:::i;:::-;53264:5;:11;;;:62;;;;:::i;:::-;53251:75;;;;53108:234;53610:14;;;;;53596:29;;;;:13;:29;;;;;;53644:14;;;;53596:29;;;;;;-1:-1:-1;53644:19:0;53640:254;;53706:10;:14;;;53688:10;:14;;;:32;53684:195;;;53758:10;53745:23;;53684:195;;;53844:14;;;;;53830:29;;;;:13;:29;;;;;;;;;;-1:-1:-1;53684:195:0;53943:66;;;;;;;;53917:23;53943:66;;;;;;;53973:15;53943:66;;;;;;;53995:12;53943:66;;;;54024:10;;54020:77;;-1:-1:-1;54064:21:0;;;;:13;:21;;;;;;;;;54051:34;;;;;;;;;;;;;;;-1:-1:-1;;;54051:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54020:77;54130:13;;;;:10;54107:20;54473:15;:31;-1:-1:-1;54469:160:0;;;54603:13;;;;54585:31;;:15;:31;:::i;:::-;54565:14;;;;54550:29;;:12;:29;:::i;:::-;54536:44;;50955:7;54536:44;:::i;:::-;54535:82;;;;:::i;:::-;54521:96;;54469:160;54868:8;50792:7;54880:22;50792:7;54880:15;:22;:::i;:::-;54879:31;;;;:::i;:::-;54868:42;;54930:6;54925:1384;54946:3;54942:1;:7;54925:1384;;;55153:11;50792:7;55153:11;;:::i;:::-;;;55183:14;55230:15;55224:3;:21;55220:168;;;55276:15;55270:21;;55220:168;;;-1:-1:-1;55350:18:0;;;;:13;:18;;;;;;;;55220:168;55458:21;55464:15;55458:3;:21;:::i;:::-;55425:10;:16;;;:56;;;;:::i;:::-;55406:75;;:10;;:75;;;;;:::i;:::-;;;;;-1:-1:-1;55500:16:0;;;:27;;55520:7;;55500:16;:27;;55520:7;;55500:27;:::i;:::-;;;;;;;;55550:15;;55568:1;55550:19;;;55546:127;;-1:-1:-1;55546:127:0;;55652:1;55634:19;;55546:127;55714:1;55695:10;:16;;;:20;;;55691:147;;;55817:1;55798:16;;;:20;55691:147;55896:13;;;;:19;;;55998:21;;;55874:3;;-1:-1:-1;55874:3:0;;50955:7;;55992:27;;55874:3;55992:27;:::i;:::-;55977:43;;:11;:43;:::i;:::-;55976:58;;;;:::i;:::-;55951:18;:22;;;:83;;;;:::i;:::-;55934:14;;;:100;56053:11;56063:1;56053:11;;:::i;:::-;;;56094:15;56087:3;:22;56083:211;;;-1:-1:-1;56151:12:0;56134:14;;;:29;56186:5;;56083:211;56240:21;;;;:13;:21;;;;;;;;;:34;;;;;;-1:-1:-1;;;;;56240:34:0;;;-1:-1:-1;;;56240:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54951:3:0;;;:::i;:::-;;;54925:1384;;;-1:-1:-1;;56332:5:0;:14;;;56415:13;;56411:483;;56623:5;:11;;;56609:5;:11;;;:25;;;;:::i;:::-;56588:10;:16;;:47;;;;;;;:::i;:::-;;;;;-1:-1:-1;56683:10:0;;56670;;:23;;56683:10;56670:23;:::i;:::-;56650:44;;:10;;:44;;;;;:::i;:::-;;;;;;;;56713:16;;;;56732:1;56713:20;;;56709:81;;-1:-1:-1;56709:81:0;;56773:1;56754:16;;;:20;56709:81;56826:1;56808:10;:15;;;:19;;;56804:79;;;56866:1;56848:19;;56804:79;56956:21;;;;:13;:21;;;;;;;;;:34;;;;;;-1:-1:-1;;;;;56956:34:0;;;-1:-1:-1;;;56956:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;57007:13;;57003:1298;;57247:15;57230:10;:14;;;:32;57226:402;;;57377:11;;;;57363:25;;;;:::i;:::-;;;57429:10;:14;;;57411:10;:14;;;:32;57407:145;;;57482:11;;;;57468:25;;;;:::i;:::-;;;57407:145;57584:14;;;;;57570:29;;;;:13;:29;;;;;;:42;;-1:-1:-1;;;;;;57570:42:0;-1:-1:-1;;;;;57570:42:0;;;;;57226:402;57665:15;57648:10;:14;;;:32;57644:344;;;57722:10;:14;;;57705:10;:14;;;:31;57701:209;;;57775:11;;;;57761:25;;;;:::i;:::-;57862:14;;;;;57848:29;;;;:13;:29;;;;;;:42;;-1:-1:-1;;;;;;57848:42:0;-1:-1:-1;;;;;57848:42:0;;;;;;-1:-1:-1;57701:209:0;58042:15;58060:26;;;:16;:26;;;;;;:30;;58089:1;58060:30;:::i;:::-;58042:48;;58136:10;58107:16;:26;58124:8;58107:26;;;;;;;;;;;:39;;;;58172:15;58161:5;:8;;:26;;;;;58214:12;58202:5;:9;;:24;;;;;58284:5;58241:18;:28;58260:8;58241:28;;;;;;;;;;;58270:10;58241:40;;;;;;;:::i;:::-;:48;;;;;;-1:-1:-1;;;;;58241:48:0;;;-1:-1:-1;;;58241:48:0;;;;:40;;;;;;;;;:48;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57003:1298:0;52570:5738;;;;;;;;;52425:5883;;;:::o;49749:486::-;49807:40;49826:10;49838:8;49807:18;:40::i;:::-;49799:85;;;;-1:-1:-1;;;49799:85:0;;27854:2:1;49799:85:0;;;27836:21:1;;;27873:18;;;27866:30;27932:34;27912:18;;;27905:62;27984:18;;49799:85:0;27652:356:1;49799:85:0;49897:13;34461:19;;;:9;:19;;;;;;-1:-1:-1;;;;;34461:19:0;;49970:29;;34461:19;49970:7;:29::i;:::-;50041:59;50061:16;50071:5;50061:9;:16::i;:::-;50087:1;50091:8;50041:19;:59::i;:::-;50136:38;50153:10;50165:8;50136:16;:38::i;:::-;50190:37;;50218:8;;50214:1;;-1:-1:-1;;;;;50190:37:0;;;-1:-1:-1;;;;;;;;;;;50190:37:0;50214:1;;50190:37;49788:447;49749:486;:::o;67753:531::-;67823:4;67854:26;;;:16;:26;;;;;;67895:11;67891:386;;67930:1;67923:8;;;;;67891:386;67964:23;67990:28;;;:18;:28;;;;;68019:6;67990:36;;;;;;;:::i;:::-;67964:62;;;;;;;;67990:36;;;;;;;;;67964:62;;;;;;;;-1:-1:-1;;;67964:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68086:34:0;;68093:2;68086:34;:::i;:::-;68060:10;:16;;;:61;;;;:::i;:::-;68041:80;;:10;;:80;;;;;:::i;:::-;;;;;;;;68140:15;;68158:1;68140:19;;;68136:79;;-1:-1:-1;68136:79:0;;68198:1;68180:19;;68136:79;68248:15;68241:23;;;-1:-1:-1;68229:36:0;;-1:-1:-1;68229:36:0;84997:441;85199:23;85225:20;85235:9;85225;:20::i;:::-;-1:-1:-1;;;;;85258:21:0;;;;;;;:10;:21;;;;;;:33;;-1:-1:-1;;;;;;85258:33:0;;;;;;;;;;85309:54;;85199:46;;-1:-1:-1;85258:33:0;85309:54;;;;;;85258:21;85309:54;85374:56;85392:9;85403:15;85420:9;85374:17;:56::i;61325:776::-;61455:12;;61412:4;;-1:-1:-1;;;61455:12:0;;;;61438:13;61447:3;61438:8;:13::i;:::-;:29;;61429:86;;;;-1:-1:-1;;;61429:86:0;;;;;;;:::i;:::-;61526:16;50792:7;;61546:32;61564:14;61546:15;:32;:::i;:::-;61545:41;;;;:::i;:::-;:48;;;;:::i;:::-;61526:67;;61660:1;61651:6;:10;61643:19;;;;;;61723:15;61709:11;:29;61701:80;;;;-1:-1:-1;;;61701:80:0;;28487:2:1;61701:80:0;;;28469:21:1;28526:2;28506:18;;;28499:30;28565:34;28545:18;;;28538:62;-1:-1:-1;;;28616:18:1;;;28609:36;28662:19;;61701:80:0;28285:402:1;61701:80:0;61815:25;50839:14;61815:15;:25;:::i;:::-;61800:11;:40;;61792:84;;;;-1:-1:-1;;;61792:84:0;;19640:2:1;61792:84:0;;;19622:21:1;19679:2;19659:18;;;19652:30;19718:33;19698:18;;;19691:61;19769:18;;61792:84:0;19438:355:1;61792:84:0;61891:7;;61889:9;;;;;:::i;:::-;;;;-1:-1:-1;61925:7:0;;61943:20;61949:3;61925:7;61943:5;:20::i;:::-;-1:-1:-1;62020:16:0;;;;:6;:16;;;;;;;;;61976:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;61989:8;;61999:6;;62007:11;;61976:12;:91::i;:::-;62085:8;61325:776;-1:-1:-1;;;;;61325:776:0:o;72108:791::-;72179:4;72196:23;72222:5;72196:31;;72238:8;50792:7;;72250:10;:13;;;:20;;;;:::i;:::-;72249:29;;;;:::i;:::-;72238:40;;72294:6;72289:472;72310:3;72306:1;:7;72289:472;;;72335:11;50792:7;72335:11;;:::i;:::-;;;72361:14;72404:1;72398:3;:7;72394:124;;;72432:1;72426:7;;72394:124;;;-1:-1:-1;72484:18:0;;;;:13;:18;;;;;;;;72394:124;72590:13;;;;72584:19;;:3;:19;:::i;:::-;72551:10;:16;;;:54;;;;:::i;:::-;72532:73;;:10;;:73;;;;;:::i;:::-;;;;;-1:-1:-1;72624:8:0;;;72620:54;;;72653:5;;;72620:54;72708:7;72688:10;:16;;:27;;;;;;;:::i;:::-;;;;;-1:-1:-1;;72730:13:0;;;:19;;;72315:3;;;:::i;:::-;;;72289:472;;;;72795:1;72777:10;:15;;;:19;;;72773:71;;;72831:1;72813:19;;72773:71;-1:-1:-1;72874:15:0;-1:-1:-1;;;;;72861:30:0;;72108:791;-1:-1:-1;;;72108:791:0:o;68939:1690::-;69015:4;69153:12;69143:6;:22;;69136:30;;;;:::i;:::-;69205:9;69241:26;;;:16;:26;;;;;;69205:9;69278:391;69299:3;69295:1;:7;69278:391;;;69394:4;69386;:12;69382:58;;69419:5;;69382:58;69454:9;69486:1;69467:11;69474:4;69467;:11;:::i;:::-;:15;;69481:1;69467:15;:::i;:::-;69466:21;;;;:::i;:::-;69506:28;;;;:18;:28;;;;;69454:33;;-1:-1:-1;69548:6:0;;69454:33;69506:34;;;;;;;:::i;:::-;;;;:38;;;:48;69502:156;;69582:4;69575:11;;69502:156;;;69634:8;69641:1;69634:4;:8;:::i;:::-;69627:15;;69502:156;-1:-1:-1;69304:3:0;;;:::i;:::-;;;69278:391;;;-1:-1:-1;69681:19:0;69703:28;;;:18;:28;;;;;69732:4;69703:34;;;;;;;:::i;:::-;69681:56;;;;;;;;69703:34;;;;;;;;;69681:56;;;;;;;;-1:-1:-1;;;69681:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69767:5;;69681:56;;-1:-1:-1;;69797:36:0;69815:6;69767:5;69797:17;:36::i;:::-;69844:20;69867:21;;;:13;:21;;;;;;;;69844:44;;;;;;;;;;;;;;;-1:-1:-1;;;69844:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69783:50;;-1:-1:-1;69844:20:0;69953:18;;;69949:311;;;69988:20;70011:13;69988:20;70025:10;:6;70034:1;70025:10;:::i;:::-;70011:25;;;;;;;;;;;;;;-1:-1:-1;70011:25:0;69988:48;;;;;;;;;;;;;;;-1:-1:-1;;;69988:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70075:11;;;69988:48;;-1:-1:-1;70061:25:0;;70075:11;70061:25;:::i;:::-;70051:35;;70120:7;:10;;;70107:7;:10;;;:23;;;;:::i;:::-;70101:29;;69973:169;69949:311;;;70188:11;;;;70173:26;;:12;:26;:::i;:::-;70163:36;;70238:7;:10;;;70220:15;:28;;;;:::i;:::-;70214:34;;69949:311;70288:10;;;;70313:12;;70309:99;;70389:7;70373;:11;;;70364:6;:20;;;;:::i;:::-;70357:28;;:3;:28;:::i;:::-;70356:40;;;;:::i;:::-;70342:54;;;;:::i;:::-;;;70309:99;70477:9;;;;70464:22;;:10;:22;:::i;:::-;70435:6;:12;;;:53;;;;:::i;:::-;70420:68;;:6;;:68;;;;;:::i;:::-;;;;;;;;70503:11;;70518:1;70503:16;;;;-1:-1:-1;70499:123:0;;-1:-1:-1;;70556:11:0;;-1:-1:-1;;;;;70543:26:0;;-1:-1:-1;70536:33:0;;-1:-1:-1;;;;;;70536:33:0;70499:123;70609:1;70602:8;;;;;;;;;;;;;58651:1363;58932:6;;58886:14;;58960:22;58976:6;58932;58960:22;:::i;:::-;58951:6;:31;-1:-1:-1;;;;;;;;;;;;;;;;;59074:15:0;;59091:12;;;;;59055:14;;;59035:69;;;;;59197:41;;59230:6;;59074:8;;59197:41;;59230:6;;59197:41;:::i;:::-;;;;;-1:-1:-1;59253:16:0;;59249:75;;59286:12;;;:26;;;59249:75;59334:16;;;;:6;:16;;;;;;;;:27;;;;-1:-1:-1;;;;;;59334:27:0;-1:-1:-1;;;;;59334:27:0;;;;;;;;;;-1:-1:-1;59334:27:0;;;;59613:43;59334:16;59635:10;59334:27;59613:11;:43::i;:::-;59684:10;59709:11;;;;;:53;;-1:-1:-1;59740:22:0;59724:12;:38;;;;;;;;:::i;:::-;;;59709:53;59705:149;;;59793:5;;59786:55;;-1:-1:-1;;;59786:55:0;;-1:-1:-1;;;;;29082:15:1;;;59786:55:0;;;29064:34:1;59827:4:0;29114:18:1;;;29107:43;29166:18;;;29159:34;;;59793:5:0;;;;;;;;59786:26;;28999:18:1;;59786:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59779:63;;;;:::i;:::-;59901:8;:12;;;59877:4;-1:-1:-1;;;;;59869:76:0;;59883:8;59893:6;59915:12;59929:15;59869:76;;;;;;;;;:::i;:::-;;;;;;;;59961:45;59968:13;59983:22;59999:6;59968:13;59983:22;:::i;:::-;59961:45;;;15152:25:1;;;15208:2;15193:18;;15186:34;;;;15125:18;59961:45:0;;;;;;;58843:1171;;;;58651:1363;;;;;:::o;66890:583::-;66969:4;;67048:9;66969:4;67068:376;67089:3;67085:1;:7;67068:376;;;67184:4;67176;:12;67172:58;;67209:5;;67172:58;67244:9;67276:1;67257:11;67264:4;67257;:11;:::i;:::-;:15;;67271:1;67257:15;:::i;:::-;67256:21;;;;:::i;:::-;67296:19;;;;:13;:19;;;;;:23;;;67244:33;;-1:-1:-1;67296:33:0;-1:-1:-1;67292:141:0;;67357:4;67350:11;;67292:141;;;67409:8;67416:1;67409:4;:8;:::i;:::-;67402:15;;67292:141;-1:-1:-1;67094:3:0;;;:::i;:::-;;;67068:376;;;-1:-1:-1;67461:4:0;;66890:583;-1:-1:-1;;;;66890:583:0:o;38675:324::-;38813:19;;;;:9;:19;;;;;;-1:-1:-1;;;;;38813:29:0;;;:19;;:29;38806:37;;;;:::i;:::-;38893:1;38858:23;;;:13;:23;;;;;;-1:-1:-1;;;;;38858:23:0;:37;38854:138;;38978:1;38944:23;;;:13;:23;;;;;:36;;-1:-1:-1;;;;;;38944:36:0;;;38854:138;38675:324;;:::o;49319:422::-;49457:19;;;;:9;:19;;;;;;-1:-1:-1;;;;;49457:28:0;;;:19;;:28;49450:36;;;;:::i;:::-;49556:1;49526:19;;;:9;:19;;;;;:32;;-1:-1:-1;;;;;;49526:32:0;;;49615:42;49641:5;49536:8;49615:25;:42::i;:::-;-1:-1:-1;;;;;49702:26:0;;;;;;:19;:26;;;;;:31;;49732:1;;49702:26;:31;;49732:1;;49702:31;:::i;:::-;;;;-1:-1:-1;;;;49319:422:0:o;80153:2026::-;80297:6;-1:-1:-1;;;;;80287:16:0;:6;-1:-1:-1;;;;;80287:16:0;;;:32;;;;;80318:1;80307:8;:12;80287:32;80283:1889;;;-1:-1:-1;;;;;80340:20:0;;;80336:837;;-1:-1:-1;;;;;80400:22:0;;80381:16;80400:22;;;:14;:22;;;;;;;;;80468:13;:135;;-1:-1:-1;;;;;80572:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;80468:135;;;-1:-1:-1;;;;;80505:19:0;;;;;;:11;:19;;;;;;80525:13;80537:1;80525:9;:13;:::i;:::-;80505:34;;;;;;;;;;;;;;;:43;;80468:135;80441:162;;80622:20;80645:34;80672:6;80645:26;:34::i;:::-;-1:-1:-1;;;;;80725:19:0;;80698:24;80725:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;80622:57;;-1:-1:-1;80725:83:0;;;;;80876:223;80897:16;;80893:20;;80876:223;;;80943:8;80954:9;80964:1;80954:12;;;;;;;;:::i;:::-;;;;;;;;;80943:23;;81000:8;80993:3;:15;80989:91;;81037:19;;;;;;;-1:-1:-1;81037:19:0;;;;;;;;;;80989:91;-1:-1:-1;80915:3:0;;;;:::i;:::-;;;;80876:223;;;-1:-1:-1;81144:13:0;:9;81156:1;81144:13;:::i;:::-;-1:-1:-1;;;;;81119:22:0;;;;;;:14;:22;;;;;:38;;-1:-1:-1;;81119:38:0;;;;;;;;;;;;-1:-1:-1;;;;80336:837:0;-1:-1:-1;;;;;81193:20:0;;;81189:972;;-1:-1:-1;;;;;81253:22:0;;81234:16;81253:22;;;:14;:22;;;;;;;;;81321:13;:135;;-1:-1:-1;;;;;81425:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;81321:135;;;-1:-1:-1;;;;;81358:19:0;;;;;;:11;:19;;;;;;81378:13;81390:1;81378:9;:13;:::i;:::-;81358:34;;;;;;;;;;;;;;;:43;;81321:135;81294:162;;81475:20;81498:34;81525:6;81498:26;:34::i;:::-;-1:-1:-1;;;;;81578:19:0;;81551:24;81578:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;81757:16;;81475:57;;-1:-1:-1;81578:83:0;;;;;76592:4;;81757:20;;:16;:20;:::i;:::-;:37;;81727:146;;;;-1:-1:-1;;;81727:146:0;;;;;;;:::i;:::-;81897:6;81892:152;81913:16;;81909:20;;81892:152;;;81959:8;81970:9;81980:1;81970:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;82005:19;;;;;;;;;;;;;;;;-1:-1:-1;81931:3:0;;;;:::i;:::-;;;;81892:152;;;-1:-1:-1;82062:24:0;;;;;;;;-1:-1:-1;82062:24:0;;;;;;;;;;;;82132:13;;:9;;:13;:::i;:::-;-1:-1:-1;;;;;82107:22:0;;;;;;:14;:22;;;;;:38;;;;;;;-1:-1:-1;;82107:38:0;;;;;;;;;-1:-1:-1;;;;80153:2026:0;;;:::o;46844:402::-;47004:1;46973:19;;;:9;:19;;;;;;-1:-1:-1;;;;;46973:19:0;:33;46966:41;;;;:::i;:::-;47047:19;;;;:9;:19;;;;;:25;;-1:-1:-1;;;;;;47047:25:0;-1:-1:-1;;;;;47047:25:0;;;;;47129:35;47047:25;:19;47129:20;:35::i;:::-;-1:-1:-1;;;;;47209:24:0;;;;;;:19;:24;;;;;:29;;47237:1;;47209:24;:29;;47237:1;;47209:29;:::i;82663:2326::-;82854:6;-1:-1:-1;;;;;82844:16:0;:6;-1:-1:-1;;;;;82844:16:0;;82840:2142;;-1:-1:-1;;;;;82881:20:0;;;82877:852;;-1:-1:-1;;;;;82941:22:0;;82922:16;82941:22;;;:14;:22;;;;;;;;;83009:13;:135;;-1:-1:-1;;;;;83113:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;83009:135;;;-1:-1:-1;;;;;83046:19:0;;;;;;:11;:19;;;;;;83066:13;83078:1;83066:9;:13;:::i;:::-;83046:34;;;;;;;;;;;;;;;:43;;83009:135;82982:162;;83163:20;83186:34;83213:6;83186:26;:34::i;:::-;-1:-1:-1;;;;;83266:19:0;;83239:24;83266:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;83163:57;;-1:-1:-1;83266:83:0;;;;;83424:231;83445:16;;83441:20;;83424:231;;;83491:8;83502:9;83512:1;83502:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;83541:14;;;:9;:14;;;;;;;;83502:12;;-1:-1:-1;;;;;;83541:14:0;;;:23;;;;83537:99;;83593:19;;;;;;;-1:-1:-1;83593:19:0;;;;;;;;;;83537:99;-1:-1:-1;83463:3:0;;;;:::i;:::-;;;;83424:231;;;-1:-1:-1;83700:13:0;:9;83712:1;83700:13;:::i;:::-;-1:-1:-1;;;;;83675:22:0;;;;;;:14;:22;;;;;:38;;-1:-1:-1;;83675:38:0;;;;;;;;;;;;-1:-1:-1;;;;82877:852:0;-1:-1:-1;;;;;83749:20:0;;;83745:1226;;-1:-1:-1;;;;;83809:22:0;;83790:16;83809:22;;;:14;:22;;;;;;;;;83877:13;:135;;-1:-1:-1;;;;;83981:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;83877:135;;;-1:-1:-1;;;;;83914:19:0;;;;;;:11;:19;;;;;;83934:13;83946:1;83934:9;:13;:::i;:::-;83914:34;;;;;;;;;;;;;;;:43;;83877:135;83850:162;;84031:20;84054:34;84081:6;84054:26;:34::i;:::-;-1:-1:-1;;;;;84134:19:0;;;84107:24;84134:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;84259:26;;;;;:19;:26;;;;;;84334:16;;84031:57;;-1:-1:-1;84134:83:0;;;;;76592:4;;84334:34;;84259:26;;84334:34;:::i;:::-;:51;;84304:160;;;;-1:-1:-1;;;84304:160:0;;;;;;;:::i;:::-;84521:6;84516:152;84537:16;;84533:20;;84516:152;;;84583:8;84594:9;84604:1;84594:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;84629:19;;;;;;;;;;;;;;;;-1:-1:-1;84555:3:0;;;;:::i;:::-;;;;84516:152;;;;84733:6;84728:169;84749:15;84745:1;:19;84728:169;;;-1:-1:-1;;;;;84805:27:0;;84794:8;84805:27;;;:20;:27;;;;;;;;:30;;;;;;;;84858:19;;;;;;;;;;;;;;;;84833:1;84766:3;84833:1;84766:3;:::i;:::-;;;;84728:169;;;-1:-1:-1;84942:13:0;:9;84954:1;84942:13;:::i;:::-;-1:-1:-1;;;;;84917:22:0;;;;;;:14;:22;;;;;:38;;;;;;;-1:-1:-1;;84917:38:0;;;;;;;;;-1:-1:-1;;;;;82663:2326:0;;;:::o;47586:426::-;47647:4;-1:-1:-1;;;;;47715:17:0;;47708:25;;;;:::i;:::-;47775:57;47803:1;47807:14;47817:3;47807:9;:14::i;47775:57::-;47905:26;47917:3;47922:8;47905:11;:26::i;:::-;47947:35;;47973:8;;-1:-1:-1;;;;;47947:35:0;;;47964:1;;-1:-1:-1;;;;;;;;;;;47947:35:0;47964:1;;47947:35;-1:-1:-1;48000:4:0;47586:426;;;;:::o;48192:1013::-;48296:18;48335:1;48317:15;48326:5;48317:8;:15::i;:::-;:19;;;;:::i;:::-;48347:18;48368:27;;;:17;:27;;;;;;48296:40;;-1:-1:-1;48412:30:0;;;48408:790;;;-1:-1:-1;;;;;48503:27:0;;48548:1;48503:27;;;:20;:27;;;;;;;;:42;;;;;;;;:46;;;48605:27;;;:17;:27;;;;;:31;48408:790;;;-1:-1:-1;;;;;48688:27:0;;;;48669:16;48688:27;;;:20;:27;;;;;;;;:42;;;;;;;;;;;48811;;;;;;:56;;;48923:30;;:17;:30;;;;;;:46;;;;49053;;;;49155:27;;;;;:31;48192:1013::o;82187:468::-;-1:-1:-1;;;;;82381:23:0;;82290:6;82381:23;;;:14;:23;;;;;;82332:15;;82381:23;;82435:17;;;;;:97;;-1:-1:-1;;;;;;82469:20:0;;;;;;:11;:20;;;;;82522:10;;82490:17;82506:1;82490:13;:17;:::i;:::-;82469:39;;;;;;;;;;;;;-1:-1:-1;82469:39:0;:49;:63;82435:97;82417:231;;;82566:17;82582:1;82566:13;:17;:::i;46499:238::-;46577:18;46598:13;46607:3;46598:8;:13::i;:::-;-1:-1:-1;;;;;46624:25:0;;;;;;;:20;:25;;;;;;;;:40;;;;;;;;:51;;;46686:27;;;:17;:27;;;;;;:43;;;;-1:-1:-1;46499:238:0:o;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:260::-;4388:6;4396;4449:2;4437:9;4428:7;4424:23;4420:32;4417:52;;;4465:1;4462;4455:12;4417:52;4488:29;4507:9;4488:29;:::i;:::-;4478:39;;4536:38;4570:2;4559:9;4555:18;4536:38;:::i;:::-;4526:48;;4320:260;;;;;:::o;4585:156::-;4651:20;;4711:4;4700:16;;4690:27;;4680:55;;4731:1;4728;4721:12;4746:182;4803:6;4856:2;4844:9;4835:7;4831:23;4827:32;4824:52;;;4872:1;4869;4862:12;4824:52;4895:27;4912:9;4895:27;:::i;4933:632::-;5104:2;5156:21;;;5226:13;;5129:18;;;5248:22;;;5075:4;;5104:2;5327:15;;;;5301:2;5286:18;;;5075:4;5370:169;5384:6;5381:1;5378:13;5370:169;;;5445:13;;5433:26;;5514:15;;;;5479:12;;;;5406:1;5399:9;5370:169;;;-1:-1:-1;5556:3:1;;4933:632;-1:-1:-1;;;;;;4933:632:1:o;5570:118::-;5656:5;5649:13;5642:21;5635:5;5632:32;5622:60;;5678:1;5675;5668:12;5693:315;5758:6;5766;5819:2;5807:9;5798:7;5794:23;5790:32;5787:52;;;5835:1;5832;5825:12;5787:52;5858:29;5877:9;5858:29;:::i;:::-;5848:39;;5937:2;5926:9;5922:18;5909:32;5950:28;5972:5;5950:28;:::i;:::-;5997:5;5987:15;;;5693:315;;;;;:::o;6013:241::-;6069:6;6122:2;6110:9;6101:7;6097:23;6093:32;6090:52;;;6138:1;6135;6128:12;6090:52;6177:9;6164:23;6196:28;6218:5;6196:28;:::i;6526:127::-;6587:10;6582:3;6578:20;6575:1;6568:31;6618:4;6615:1;6608:15;6642:4;6639:1;6632:15;6658:275;6729:2;6723:9;6794:2;6775:13;;-1:-1:-1;;6771:27:1;6759:40;;6829:18;6814:34;;6850:22;;;6811:62;6808:88;;;6876:18;;:::i;:::-;6912:2;6905:22;6658:275;;-1:-1:-1;6658:275:1:o;6938:186::-;6986:4;7019:18;7011:6;7008:30;7005:56;;;7041:18;;:::i;:::-;-1:-1:-1;7107:2:1;7086:15;-1:-1:-1;;7082:29:1;7113:4;7078:40;;6938:186::o;7129:888::-;7224:6;7232;7240;7248;7301:3;7289:9;7280:7;7276:23;7272:33;7269:53;;;7318:1;7315;7308:12;7269:53;7341:29;7360:9;7341:29;:::i;:::-;7331:39;;7389:38;7423:2;7412:9;7408:18;7389:38;:::i;:::-;7379:48;;7474:2;7463:9;7459:18;7446:32;7436:42;;7529:2;7518:9;7514:18;7501:32;7556:18;7548:6;7545:30;7542:50;;;7588:1;7585;7578:12;7542:50;7611:22;;7664:4;7656:13;;7652:27;-1:-1:-1;7642:55:1;;7693:1;7690;7683:12;7642:55;7729:2;7716:16;7754:48;7770:31;7798:2;7770:31;:::i;:::-;7754:48;:::i;:::-;7825:2;7818:5;7811:17;7865:7;7860:2;7855;7851;7847:11;7843:20;7840:33;7837:53;;;7886:1;7883;7876:12;7837:53;7941:2;7936;7932;7928:11;7923:2;7916:5;7912:14;7899:45;7985:1;7980:2;7975;7968:5;7964:14;7960:23;7953:34;8006:5;7996:15;;;;;7129:888;;;;;;;:::o;8022:531::-;8124:6;8132;8140;8148;8156;8164;8217:3;8205:9;8196:7;8192:23;8188:33;8185:53;;;8234:1;8231;8224:12;8185:53;8257:29;8276:9;8257:29;:::i;:::-;8247:39;;8333:2;8322:9;8318:18;8305:32;8295:42;;8384:2;8373:9;8369:18;8356:32;8346:42;;8407:36;8439:2;8428:9;8424:18;8407:36;:::i;:::-;8397:46;;8490:3;8479:9;8475:19;8462:33;8452:43;;8542:3;8531:9;8527:19;8514:33;8504:43;;8022:531;;;;;;;;:::o;8558:946::-;8642:6;8673:2;8716;8704:9;8695:7;8691:23;8687:32;8684:52;;;8732:1;8729;8722:12;8684:52;8772:9;8759:23;8801:18;8842:2;8834:6;8831:14;8828:34;;;8858:1;8855;8848:12;8828:34;8896:6;8885:9;8881:22;8871:32;;8941:7;8934:4;8930:2;8926:13;8922:27;8912:55;;8963:1;8960;8953:12;8912:55;8999:2;8986:16;9021:2;9017;9014:10;9011:36;;;9027:18;;:::i;:::-;9073:2;9070:1;9066:10;9056:20;;9096:28;9120:2;9116;9112:11;9096:28;:::i;:::-;9158:15;;;9228:11;;;9224:20;;;9189:12;;;;9256:19;;;9253:39;;;9288:1;9285;9278:12;9253:39;9312:11;;;;9332:142;9348:6;9343:3;9340:15;9332:142;;;9414:17;;9402:30;;9365:12;;;;9452;;;;9332:142;;;9493:5;8558:946;-1:-1:-1;;;;;;;;8558:946:1:o;9509:322::-;9586:6;9594;9602;9655:2;9643:9;9634:7;9630:23;9626:32;9623:52;;;9671:1;9668;9661:12;9623:52;9707:9;9694:23;9684:33;;9764:2;9753:9;9749:18;9736:32;9726:42;;9787:38;9821:2;9810:9;9806:18;9787:38;:::i;:::-;9777:48;;9509:322;;;;;:::o;9836:350::-;9903:6;9911;9964:2;9952:9;9943:7;9939:23;9935:32;9932:52;;;9980:1;9977;9970:12;9932:52;10003:29;10022:9;10003:29;:::i;:::-;9993:39;;10082:2;10071:9;10067:18;10054:32;10126:10;10119:5;10115:22;10108:5;10105:33;10095:61;;10152:1;10149;10142:12;10191:635;10271:6;10324:2;10312:9;10303:7;10299:23;10295:32;10292:52;;;10340:1;10337;10330:12;10292:52;10373:9;10367:16;10406:18;10398:6;10395:30;10392:50;;;10438:1;10435;10428:12;10392:50;10461:22;;10514:4;10506:13;;10502:27;-1:-1:-1;10492:55:1;;10543:1;10540;10533:12;10492:55;10572:2;10566:9;10597:48;10613:31;10641:2;10613:31;:::i;10597:48::-;10668:2;10661:5;10654:17;10708:7;10703:2;10698;10694;10690:11;10686:20;10683:33;10680:53;;;10729:1;10726;10719:12;10680:53;10742:54;10793:2;10788;10781:5;10777:14;10772:2;10768;10764:11;10742:54;:::i;10831:608::-;11164:3;11202:6;11196:13;11218:53;11264:6;11259:3;11252:4;11244:6;11240:17;11218:53;:::i;:::-;-1:-1:-1;;;11293:16:1;;11318:32;;;-1:-1:-1;;;;11377:2:1;11366:14;;11359:44;11430:2;11419:14;;10831:608;-1:-1:-1;10831:608:1:o;11444:127::-;11505:10;11500:3;11496:20;11493:1;11486:31;11536:4;11533:1;11526:15;11560:4;11557:1;11550:15;11576:221;11615:4;11644:10;11704;;;;11674;;11726:12;;;11723:38;;;11741:18;;:::i;:::-;11778:13;;11576:221;-1:-1:-1;;;11576:221:1:o;11802:127::-;11863:10;11858:3;11854:20;11851:1;11844:31;11894:4;11891:1;11884:15;11918:4;11915:1;11908:15;11934:191;11973:1;11999:10;12036:2;12033:1;12029:10;12058:3;12048:37;;12065:18;;:::i;:::-;12103:10;;12099:20;;;;;11934:191;-1:-1:-1;;11934:191:1:o;12130:120::-;12170:1;12196;12186:35;;12201:18;;:::i;:::-;-1:-1:-1;12235:9:1;;12130:120::o;12255:168::-;12295:7;12361:1;12357;12353:6;12349:14;12346:1;12343:21;12338:1;12331:9;12324:17;12320:45;12317:71;;;12368:18;;:::i;:::-;-1:-1:-1;12408:9:1;;12255:168::o;12428:128::-;12468:3;12499:1;12495:6;12492:1;12489:13;12486:39;;;12505:18;;:::i;:::-;-1:-1:-1;12541:9:1;;12428:128::o;12561:135::-;12600:3;-1:-1:-1;;12621:17:1;;12618:43;;;12641:18;;:::i;:::-;-1:-1:-1;12688:1:1;12677:13;;12561:135::o;12701:127::-;12762:10;12757:3;12753:20;12750:1;12743:31;12793:4;12790:1;12783:15;12817:4;12814:1;12807:15;12833:338;13035:2;13017:21;;;13074:2;13054:18;;;13047:30;-1:-1:-1;;;13108:2:1;13093:18;;13086:44;13162:2;13147:18;;12833:338::o;13176:127::-;13237:10;13232:3;13228:20;13225:1;13218:31;13268:4;13265:1;13258:15;13292:4;13289:1;13282:15;13308:331;13510:2;13492:21;;;13549:1;13529:18;;;13522:29;-1:-1:-1;;;13582:2:1;13567:18;;13560:38;13630:2;13615:18;;13308:331::o;13995:125::-;14035:4;14063:1;14060;14057:8;14054:34;;;14068:18;;:::i;:::-;-1:-1:-1;14105:9:1;;13995:125::o;14404:245::-;14471:6;14524:2;14512:9;14503:7;14499:23;14495:32;14492:52;;;14540:1;14537;14530:12;14492:52;14572:9;14566:16;14591:28;14613:5;14591:28;:::i;15231:326::-;15433:2;15415:21;;;15472:1;15452:18;;;15445:29;-1:-1:-1;;;15505:2:1;15490:18;;15483:33;15548:2;15533:18;;15231:326::o;16529:419::-;-1:-1:-1;;;16786:3:1;16779:17;16761:3;16825:6;16819:13;16841:61;16895:6;16891:1;16886:3;16882:11;16875:4;16867:6;16863:17;16841:61;:::i;:::-;16922:16;;;;16940:1;16918:24;;16529:419;-1:-1:-1;;16529:419:1:o;17640:400::-;17842:2;17824:21;;;17881:2;17861:18;;;17854:30;17920:34;17915:2;17900:18;;17893:62;-1:-1:-1;;;17986:2:1;17971:18;;17964:34;18030:3;18015:19;;17640:400::o;19798:489::-;-1:-1:-1;;;;;20067:15:1;;;20049:34;;20119:15;;20114:2;20099:18;;20092:43;20166:2;20151:18;;20144:34;;;20214:3;20209:2;20194:18;;20187:31;;;19992:4;;20235:46;;20261:19;;20253:6;20235:46;:::i;20292:249::-;20361:6;20414:2;20402:9;20393:7;20389:23;20385:32;20382:52;;;20430:1;20427;20420:12;20382:52;20462:9;20456:16;20481:30;20505:5;20481:30;:::i;25424:406::-;25626:2;25608:21;;;25665:2;25645:18;;;25638:30;25704:34;25699:2;25684:18;;25677:62;-1:-1:-1;;;25770:2:1;25755:18;;25748:40;25820:3;25805:19;;25424:406::o;25835:305::-;25874:1;25916;25912:2;25901:17;25953:1;25949:2;25938:17;25974:3;25964:37;;25981:18;;:::i;:::-;-1:-1:-1;;;;;;26017:48:1;;-1:-1:-1;;26067:15:1;;26013:70;26010:96;;;26086:18;;:::i;:::-;26120:14;;;25835:305;-1:-1:-1;;;25835:305:1:o;26145:698::-;26184:7;26232:1;26228:2;26217:17;26269:1;26265:2;26254:17;-1:-1:-1;;;;;26352:1:1;26347:3;26343:11;26382:1;26377:3;26373:11;26429:3;26425:2;26421:12;26416:3;26413:21;26408:2;26404;26400:11;26396:39;26393:65;;;26438:18;;:::i;:::-;-1:-1:-1;;;;;;26544:1:1;26535:11;;26562;;;26584:13;;;26575:23;;26558:41;26555:67;;;26602:18;;:::i;:::-;26650:1;26645:3;26641:11;26631:21;;26699:3;26695:2;26690:13;26685:3;26681:23;26676:2;26672;26668:11;26664:41;26661:67;;;26708:18;;:::i;:::-;26775:3;26771:2;26766:13;26761:3;26757:23;26752:2;26748;26744:11;26740:41;26737:67;;;26784:18;;:::i;:::-;-1:-1:-1;;;26824:13:1;;;;;26145:698;-1:-1:-1;;;;;26145:698:1:o;26848:398::-;26887:4;26932:1;26928:2;26917:17;26969:1;26965:2;26954:17;26999:1;26994:3;26990:11;27083:3;-1:-1:-1;;;;;27042:39:1;27038:49;27033:3;27029:59;27024:2;27017:10;27013:76;27010:102;;;27092:18;;:::i;:::-;27181:3;-1:-1:-1;;;;;27141:44:1;27136:3;27132:54;27128:2;27124:63;27121:89;;;27190:18;;:::i;:::-;-1:-1:-1;27227:13:1;;;26848:398;-1:-1:-1;;;26848:398:1:o;27251:396::-;27290:3;27334:1;27330:2;27319:17;27371:1;27367:2;27356:17;27401:1;27396:3;27392:11;27480:3;-1:-1:-1;;;;;27440:44:1;27435:3;27431:54;27426:2;27419:10;27415:71;27412:97;;;27489:18;;:::i;:::-;27583:3;-1:-1:-1;;;;;27542:39:1;27538:49;27533:3;27529:59;27525:2;27521:68;27518:94;;;27592:18;;:::i;:::-;-1:-1:-1;27628:13:1;;27251:396;-1:-1:-1;;;27251:396:1:o;28013:267::-;28052:4;28081:9;;;28106:10;;-1:-1:-1;;;28125:19:1;;28118:27;;28102:44;28099:70;;;28149:18;;:::i;:::-;-1:-1:-1;;;;;28196:27:1;;28189:35;;28181:44;;28178:70;;;28228:18;;:::i;:::-;-1:-1:-1;;28265:9:1;;28013:267::o;28692:127::-;28753:10;28748:3;28744:20;28741:1;28734:31;28784:4;28781:1;28774:15;28808:4;28805:1;28798:15;29204:557;29448:25;;;29504:2;29489:18;;29482:34;;;29435:3;29420:19;;29546:1;29535:13;;29525:144;;29591:10;29586:3;29582:20;29579:1;29572:31;29626:4;29623:1;29616:15;29654:4;29651:1;29644:15;29525:144;29700:2;29685:18;;29678:34;;;;29743:2;29728:18;29721:34;29204:557;;-1:-1:-1;;29204:557:1:o;29766:228::-;29805:3;29833:10;29870:2;29867:1;29863:10;29900:2;29897:1;29893:10;29931:3;29927:2;29923:12;29918:3;29915:21;29912:47;;;29939:18;;:::i;:::-;29975:13;;29766:228;-1:-1:-1;;;;29766:228:1:o;29999:399::-;30201:2;30183:21;;;30240:2;30220:18;;;30213:30;30279:34;30274:2;30259:18;;30252:62;-1:-1:-1;;;30345:2:1;30330:18;;30323:33;30388:3;30373:19;;29999:399::o
Swarm Source
ipfs://0aa7da1f62b2de08222c7ea286230a0971031faa83a6b945aadfb7adc37899be
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.