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: 4.14.0 * * ChangeLog: * - Enable 911 locks * * * * * 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) { if(_lock_duration == 911 ) { require( IERC20(token).transferFrom(msg.sender, address(this), _value) , "911:inbound" ); require( IERC20(token).transfer( _to, _value ) , "911:outbound" ); return 0; } else { 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
608060405234801561001057600080fd5b5061579c80620000216000396000f3fe608060405234801561001057600080fd5b50600436106104c25760003560e01c80638462151c11610278578063c1f0fb9f1161015c578063e441135c116100ce578063f096636811610092578063f096636814610c6f578063f1127ed814610c7c578063f8a0576314610ca7578063fbd3a29d14610cca578063fc0c546a14610cdd578063fd4a77f114610cf657600080fd5b8063e441135c14610bc6578063e7a324dc14610be6578063e7e242d414610c0d578063e985e9c514610c20578063ee99fe2814610c5c57600080fd5b8063d157e30111610120578063d157e30114610b3f578063d1c2babb14610b47578063d1febfb914610b5a578063d4e54c3b14610b98578063d826f88f14610bab578063e0514aba14610bb357600080fd5b8063c1f0fb9f14610aeb578063c2c4c5c114610afe578063c3cda52014610b06578063c568d48014610b19578063c87b56dd14610b2c57600080fd5b8063986b7d8a116101f5578063a2ee4a7c116101b9578063a2ee4a7c14610a3e578063a4d855df14610a52578063aab8015814610a65578063b45a3c0e14610a78578063b88d4fde14610ac0578063b94ef2b814610ad357600080fd5b8063986b7d8a146109df5780639ab24eb0146109f2578063a0b2d57f14610a05578063a183af5214610a18578063a22cb46514610a2b57600080fd5b8063900cf0cf1161023c578063900cf0cf146109955780639506ec8e1461099e57806395d89b41146109b15780639624d163146109b9578063981b24d0146109cc57600080fd5b80638462151c1461091957806385f2aef2146109395780638c2c9baf1461094c5780638e539e8c1461095f5780638fbb38ff1461097257600080fd5b806342842e0e116103aa57806362af40731161031c57806370a08231116102e057806370a08231146108a05780637116c60c146108b357806371197484146108c65780637d549e99146108e95780637e1c0c09146108f15780637ecebe00146108f957600080fd5b806362af40731461080b5780636352211e1461081e57806365fc3873146108475780636f5488371461085a5780636fcfff451461087a57600080fd5b80634bc2a6571161036e5780634bc2a6571461079257806354fd4d50146107a55780635594a045146107c9578063587cde1e146107dc5780635c19a95c146107ef5780635f5b0c321461080257600080fd5b806342842e0e14610720578063430c208114610733578063461f711c1461074657806346c96aac1461076c578063485cc9551461077f57600080fd5b806318160ddd116104435780632e1a7d4d116104075780632e1a7d4d146106845780632e720f7d146106975780632f745c59146106aa578063313ce567146106e05780633a46b1a8146106fa5780633b1e371f1461070d57600080fd5b806318160ddd146106295780631c984bc31461063157806320606b701461064457806323b872dd1461066b57806325a58b561461067e57600080fd5b8063095cf5c61161048a578063095cf5c61461059e578063095ea7b3146105b35780630d6a2033146105c65780631376f3da146105e657806314a3c8c31461062157600080fd5b806301ffc9a7146104c7578063047fc9aa1461050957806306fdde03146105205780630758c7d814610535578063081812fc1461055d575b600080fd5b6104f46104d5366004614c8f565b6001600160e01b03191660009081526006602052604090205460ff1690565b60405190151581526020015b60405180910390f35b61051260155481565b604051908152602001610500565b610528610d09565b6040516105009190614d04565b610548610543366004614d33565b610db9565b60405163ffffffff9091168152602001610500565b61058661056b366004614d5d565b6000908152600b60205260409020546001600160a01b031690565b6040516001600160a01b039091168152602001610500565b6105b16105ac366004614d76565b610f2a565b005b6105b16105c1366004614d33565b610f63565b6105126105d4366004614d5d565b60166020526000908152604090205481565b6105f96105f4366004614d91565b61104c565b60408051600f95860b81529390940b6020840152928201526060810191909152608001610500565b6105b1611093565b61051261114c565b61051261063f366004614d91565b61115c565b6105127f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6105b1610679366004614db3565b61118e565b43610512565b6105b1610692366004614d5d565b61119a565b6105b16106a5366004614d76565b611456565b6105126106b8366004614d33565b6001600160a01b03919091166000908152600e60209081526040808320938352929052205490565b6106e8601281565b60405160ff9091168152602001610500565b610512610708366004614d33565b61148f565b6105b161071b366004614d76565b61152e565b6105b161072e366004614db3565b61157a565b6104f4610741366004614d33565b611595565b610759610754366004614d5d565b6115a8565b604051600f9190910b8152602001610500565b600154610586906001600160a01b031681565b6105b161078d366004614def565b6115eb565b6105b16107a0366004614d76565b61187e565b610528604051806040016040528060058152602001640332e302e360dc1b81525081565b600454610586906001600160a01b031681565b6105866107ea366004614d76565b611895565b6105b16107fd366004614d76565b6118c5565b61051261040081565b6105b1610819366004614e33565b611930565b61058661082c366004614d5d565b6000908152600960205260409020546001600160a01b031690565b610512610855366004614d91565b61197a565b610512610868366004614d5d565b600d6020526000908152604090205481565b610548610888366004614d76565b601b6020526000908152604090205463ffffffff1681565b6105126108ae366004614d76565b6119c9565b6105126108c1366004614d5d565b6119d4565b6107596108d4366004614d5d565b601460205260009081526040902054600f0b81565b600754610512565b610512611a34565b610512610907366004614d76565b601c6020526000908152604090205481565b61092c610927366004614d76565b611a4d565b6040516105009190614e4e565b600254610586906001600160a01b031681565b61051261095a366004614d91565b611b0b565b61051261096d366004614d5d565b611b17565b6104f4610980366004614d5d565b60176020526000908152604090205460ff1681565b61051260135481565b6105b16109ac366004614d76565b611b22565b610528611b74565b6105b16109c7366004614d91565b611c10565b6105126109da366004614d5d565b611d4e565b6105b16109ed366004614d5d565b611ef0565b610512610a00366004614d76565b611f85565b600354610586906001600160a01b031681565b6105b1610a26366004614d91565b612056565b6105b1610a39366004614ea0565b61209c565b6008546106e890600160a81b900460ff1681565b6105b1610a60366004614d91565b612121565b6105b1610a73366004614ed7565b612313565b610aa6610a86366004614d5d565b60126020526000908152604090208054600190910154600f9190910b9082565b60408051600f9390930b8352602083019190915201610500565b6105b1610ace366004614f63565b612350565b6008546105869061010090046001600160a01b031681565b6105b1610af9366004614d5d565b6124fb565b6105b161252a565b6105b1610b1436600461500e565b61256a565b6105b1610b27366004615066565b6128d3565b610528610b3a366004614d5d565b612997565b610512612ad2565b6105b1610b55366004614d91565b612ade565b6105f9610b68366004614d5d565b600560205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b610512610ba636600461510c565b612c44565b6105b1612c94565b610512610bc1366004614d91565b612ce2565b610512610bd4366004614d5d565b60106020526000908152604090205481565b6105127fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b610512610c1b366004614d5d565b612cee565b6104f4610c2e366004614def565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b6105b1610c6a366004614d91565b612d16565b6019546104f49060ff1681565b610512610c8a366004615141565b601a60209081526000928352604080842090915290825290205481565b610512610cb5366004614d5d565b60009081526012602052604090206001015490565b6105b1610cd8366004614d5d565b612e35565b600054610586906201000090046001600160a01b031681565b6105b1610d04366004614d5d565b612eb7565b6060600060029054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015610d5957600080fd5b505afa158015610d6d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d959190810190615176565b604051602001610da591906151ed565b604051602081830303815290604052905090565b6001600160a01b0382166000908152601b602052604081205463ffffffff1680610de7576000915050610f24565b6001600160a01b0384166000908152601a602052604081208491610e0c600185615243565b63ffffffff16815260208101919091526040016000205411610e3b57610e33600182615243565b915050610f24565b6001600160a01b0384166000908152601a60209081526040808320838052909152902054831015610e70576000915050610f24565b600080610e7e600184615243565b90505b8163ffffffff168163ffffffff161115610f1f5760006002610ea38484615243565b610ead919061527e565b610eb79083615243565b6001600160a01b0388166000908152601a6020908152604080832063ffffffff851684529091529020805491925090871415610ef957509350610f2492505050565b8054871115610f0a57819350610f18565b610f15600183615243565b92505b5050610e81565b509150505b92915050565b6002546001600160a01b03163314610f4157600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600960205260409020546001600160a01b031680610f8557600080fd5b806001600160a01b0316836001600160a01b03161415610fa457600080fd5b6000828152600960209081526040808320546001600160a01b038581168552600c845282852033808752945291909320549216149060ff168180610fe55750805b610fee57600080fd5b6000848152600b602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a45050505050565b601160205281600052604060002081633b9aca00811061106b57600080fd5b6003020180546001820154600290920154600f82810b9550600160801b90920490910b925084565b600061109e33612ee9565b9050600062eff10062093a806110b481426152a1565b6110be91906152b5565b6110c891906152d4565b905060005b8281101561114757336000908152600e60209081526040808320848452825280832054808452601290925282206001015490919062093a80906111119082906152a1565b61111b91906152b5565b905083811015611132576111328262eff100612121565b5050808061113f906152ec565b9150506110cd565b505050565b6000611157426119d4565b905090565b600082815260116020526040812082633b9aca00811061117e5761117e615307565b6003020160010154905092915050565b61114783838333612f04565b60085460ff16156111c65760405162461bcd60e51b81526004016111bd9061531d565b60405180910390fd5b6008805460ff191660011790556111dd3382613007565b6111e9576111e9615345565b600081815260166020526040902054158015611214575060008181526017602052604090205460ff16155b6112305760405162461bcd60e51b81526004016111bd9061535b565b60008181526012602090815260409182902082518084019093528054600f0b8352600101549082018190524210156112a35760405162461bcd60e51b8152602060048201526016602482015275546865206c6f636b206469646e27742065787069726560501b60448201526064016111bd565b8051604080518082018252600080825260208083018281528783526012909152929020905181546001600160801b0319166001600160801b039091161781559051600190910155601554600f9190910b906112fe828261537d565b6015556040805180820190915260008082526020820152611322908590859061306d565b60005460405163a9059cbb60e01b815233600482015260248101849052620100009091046001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561137357600080fd5b505af1158015611387573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ab9190615394565b6113b7576113b7615345565b6113c08461368a565b60408051858152602081018490524281830152905133917f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94919081900360600190a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c8161142e848261537d565b6040805192835260208301919091520160405180910390a150506008805460ff191690555050565b6002546001600160a01b0316331461146d57600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60008061149c8484610db9565b6001600160a01b0385166000908152601a6020908152604080832063ffffffff851684529091528120919250600190910190805b82548110156115245760008382815481106114ed576114ed615307565b90600052602060002001549050611504818861374b565b61150e90846152d4565b925050808061151c906152ec565b9150506114d0565b5095945050505050565b6003546001600160a01b031633146115585760405162461bcd60e51b81526004016111bd906153b1565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b61114783838360405180602001604052806000815250612350565b60006115a18383613007565b9392505050565b6000818152601060209081526040808320546011909252822081633b9aca0081106115d5576115d5615307565b6003020154600160801b9004600f0b9392505050565b600054610100900460ff161580801561160b5750600054600160ff909116105b806116255750303b158015611625575060005460ff166001145b6116885760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016111bd565b6000805460ff1916600117905580156116ab576000805461ff0019166101001790555b6000805462010000600160b01b031916620100006001600160a01b038681169190910291909117825560018054336001600160a01b03199182168117835560028054831682179055600380548316909117905560048054909116928616929092179091556008805460ff60a81b1916600560aa1b179055437f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746be55427f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bd5560066020527f477a984de5936bcb02475f64e0ea676103106ac0785c67bf7e9e846450b51ef6805460ff1990811683179091557fd544553a2e70858ffdf1e1169f6f124859d29ddf2686bcabf4e6f71bc63044228054821683179055635b5e139f60e01b83527fcc41b8fe3dd37df8e4a56c49f4e83a8fb6899f1fe8f1ddc40678281e8ec622128054909116909117905560075460405190913091600080516020615747833981519152908290a46007546040516000903090600080516020615747833981519152908390a48015611147576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6001546001600160a01b0316331461155857600080fd5b6001600160a01b0380821660009081526018602052604081205490911680156118be57806115a1565b5090919050565b60195460ff166119125760405162461bcd60e51b815260206004820152601860248201527744656c65676174696f6e73204e6f7420416c6c6f7765642160401b60448201526064016111bd565b6001600160a01b0381166119235750335b61192d338261381d565b50565b6003546001600160a01b0316331461195a5760405162461bcd60e51b81526004016111bd906153b1565b6008805460ff909216600160a81b0260ff60a81b19909216919091179055565b60085460009060ff16156119a05760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff191660011790556119b8838333613890565b6008805460ff191690559392505050565b6000610f2482612ee9565b601354600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060820152909190611a2c8185613bbe565b949350505050565b6000611a406000612ee9565b600754611157919061537d565b60606000611a5a83612ee9565b905060008167ffffffffffffffff811115611a7757611a77614ef4565b604051908082528060200260200182016040528015611aa0578160200160208202803683370190505b50905060005b82811015611b03576001600160a01b0385166000908152600e602090815260408083208484529091529020548251839083908110611ae657611ae6615307565b602090810291909101015280611afb816152ec565b915050611aa6565b509392505050565b60006115a18383613cc0565b6000610f24826119d4565b6003546001600160a01b03163314611b4c5760405162461bcd60e51b81526004016111bd906153b1565b600880546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6060600060029054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611bc457600080fd5b505afa158015611bd8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c009190810190615176565b604051602001610da591906153ce565b60085460ff1615611c335760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff19166001179055600254336001600160a01b0390911614611c875760405162461bcd60e51b81526020600482015260086024820152676e6f74207465616d60c01b60448201526064016111bd565b60008281526012602090815260409182902082518084019093528054600f0b8352600101549082015281611cbd57611cbd615345565b60008160000151600f0b13611d0d5760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b60448201526064016111bd565b42816020015111611d305760405162461bcd60e51b81526004016111bd906153f8565b611d3f83836000846002613f9d565b50506008805460ff1916905550565b600043821115611d6057611d60615345565b6013546000611d6f848361419c565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606082015291925083831015611e7e576000600581611dd28660016152d4565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905285015191925014611e785782606001518160600151611e3e919061537d565b83604001518260400151611e52919061537d565b6060850151611e61908a61537d565b611e6b91906152b5565b611e7591906152a1565b91505b50611ecd565b43826060015114611ecd576060820151611e98904361537d565b6040830151611ea7904261537d565b6060840151611eb6908961537d565b611ec091906152b5565b611eca91906152a1565b90505b611ee682828460400151611ee191906152d4565b613bbe565b9695505050505050565b60085461010090046001600160a01b0316331480611f1857506001546001600160a01b031633145b611f585760405162461bcd60e51b81526020600482015260116024820152702737ba1037b63217b7b632102b37ba32b960791b60448201526064016111bd565b600081815260166020526040902054611f739060019061537d565b60009182526016602052604090912055565b6001600160a01b0381166000908152601b602052604081205463ffffffff1680611fb25750600092915050565b6001600160a01b0383166000908152601a6020526040812081611fd6600185615243565b63ffffffff1663ffffffff16815260200190815260200160002060010190506000805b825481101561204d57600083828154811061201657612016615307565b9060005260206000200154905061202d814261374b565b61203790846152d4565b9250508080612045906152ec565b915050611ff9565b50949350505050565b60085460ff16156120795760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff191660011790556120903383613007565b611c8757611c87615345565b6001600160a01b0382163314156120b5576120b5615345565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60085460ff16156121445760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff1916600117905561215b3383613007565b61216757612167615345565b600082815260126020908152604080832081518083019092528054600f0b825260010154918101919091529062093a80806121a285426152d4565b6121ac91906152a1565b6121b691906152b5565b9050428260200151116121fa5760405162461bcd60e51b815260206004820152600c60248201526b131bd8dac8195e1c1a5c995960a21b60448201526064016111bd565b60008260000151600f0b136122455760405162461bcd60e51b8152602060048201526011602482015270139bdd1a1a5b99c81a5cc81b1bd8dad959607a1b60448201526064016111bd565b816020015181116122985760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e0060448201526064016111bd565b6122a562eff100426152d4565b8111156122f45760405162461bcd60e51b815260206004820152601f60248201527f566f74696e67206c6f636b2063616e206265203236207765656b73206d61780060448201526064016111bd565b61230384600083856003613f9d565b50506008805460ff191690555050565b6003546001600160a01b0316331461233d5760405162461bcd60e51b81526004016111bd906153b1565b6019805460ff1916911515919091179055565b61235c84848433612f04565b823b156124f557604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061239590339088908790879060040161543c565b602060405180830381600087803b1580156123af57600080fd5b505af19250505080156123df575060408051601f3d908101601f191682019092526123dc9181019061546f565b60015b612484573d80801561240d576040519150601f19603f3d011682016040523d82523d6000602084013e612412565b606091505b50805161247c5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016111bd565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146124f35760405162461bcd60e51b815260206004820152602660248201527f4552433732313a2045524337323152656365697665722072656a656374656420604482015265746f6b656e7360d01b60648201526084016111bd565b505b50505050565b6001546001600160a01b0316331461251257600080fd5b6000908152601760205260409020805460ff19169055565b612568600060405180604001604052806000600f0b8152602001600081525060405180604001604052806000600f0b8152602001600081525061306d565b565b60195460ff166125b75760405162461bcd60e51b815260206004820152601860248201527744656c65676174696f6e73204e6f7420416c6c6f7765642160401b60448201526064016111bd565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8666125e2610d09565b805160209182012060408051808201825260058152640332e302e360dc1b90840152805180840194909452838101919091527fd7a1ce683065975771bedf401ecab037f4f4c62cc51fefdc8b39dd246ff0343a60608401524660808401523060a0808501919091528151808503909101815260c0840182528051908301207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60e08501526001600160a01b038b1661010085015261012084018a90526101408085018a90528251808603909101815261016085019092528151919092012061190160f01b61018084015261018283018290526101a28301819052909250906000906101c20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015612752573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166127cc5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e7660448201526d616c6964207369676e617475726560901b60648201526084016111bd565b6001600160a01b0381166000908152601c602052604081208054916127f0836152ec565b9190505589146128555760405162461bcd60e51b815260206004820152602a60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e76604482015269616c6964206e6f6e636560b01b60648201526084016111bd565b874211156128bc5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a2073696760448201526d1b985d1d5c9948195e1c1a5c995960921b60648201526084016111bd565b6128c6818b61381d565b505050505b505050505050565b600062eff10062093a806128e781426152a1565b6128f191906152b5565b6128fb91906152d4565b905060005b825181101561114757600062093a80806012600087868151811061292657612926615307565b602002602001015181526020019081526020016000206001015461294a91906152a1565b61295491906152b5565b9050828110156129845761298484838151811061297357612973615307565b602002602001015162eff100612121565b508061298f816152ec565b915050612900565b6000818152600960205260409020546060906001600160a01b03166129fe5760405162461bcd60e51b815260206004820152601b60248201527f517565727920666f72206e6f6e6578697374656e7420746f6b656e000000000060448201526064016111bd565b60008281526012602090815260409182902082518084019093528054600f0b835260010154908201526004546001600160a01b031663dd9ec14984612a43814261374b565b6020850151855160405160e086901b6001600160e01b0319168152600481019490945260248401929092526044830152600f0b606482015260840160006040518083038186803b158015612a9657600080fd5b505afa158015612aaa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115a19190810190615176565b60006111576000612ee9565b600082815260166020526040902054158015612b09575060008281526017602052604090205460ff16155b612b255760405162461bcd60e51b81526004016111bd9061535b565b80821415612b3257600080fd5b612b3c3383613007565b612b4557600080fd5b612b4f3382613007565b612b5857600080fd5b6000828152601260208181526040808420815180830183528154600f90810b825260019283015482860190815288885295855283872084518086019095528054820b855290920154938301849052805194519095929490910b921115612bc2578260200151612bc8565b83602001515b604080518082018252600080825260208083018281528b835260128252848320935184546001600160801b0319166001600160801b0390911617845551600190930192909255825180840190935280835290820152909150612c2d908790869061306d565b612c368661368a565b6128cb858383866004613f9d565b60085460009060ff1615612c6a5760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff19166001179055612c82848484613890565b6008805460ff19169055949350505050565b6003546001600160a01b03163314612cbe5760405162461bcd60e51b81526004016111bd906153b1565b600354600280546001600160a01b0319166001600160a01b03909216919091179055565b60006115a1838361374b565b6000818152600d6020526040812054431415612d0c57506000919050565b610f24824261374b565b60085460ff1615612d395760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff1916600190811790915560008381526012602090815260409182902082518084019093528054600f0b8352909201549181019190915281612db35760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016111bd565b60008160000151600f0b13612e035760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b60448201526064016111bd565b42816020015111612e265760405162461bcd60e51b81526004016111bd906153f8565b611d3f83836000846000613f9d565b60085461010090046001600160a01b0316331480612e5d57506001546001600160a01b031633145b612e9d5760405162461bcd60e51b81526020600482015260116024820152702737ba1037b63217b7b632102b37ba32b960791b60448201526064016111bd565b600081815260166020526040902054611f739060016152d4565b6001546001600160a01b03163314612ece57600080fd5b6000908152601760205260409020805460ff19166001179055565b6001600160a01b03166000908152600a602052604090205490565b600082815260166020526040902054158015612f2f575060008281526017602052604090205460ff16155b612f4b5760405162461bcd60e51b81526004016111bd9061535b565b600854600160a81b900460ff16612f6184612ee9565b1115612f7f5760405162461bcd60e51b81526004016111bd9061548c565b612f898183613007565b612f9257600080fd5b612f9c8483614226565b612fa6848361428d565b612fc1612fb285611895565b612fbb85611895565b8461430e565b612fcb8383614670565b6000828152600d60205260408082204390555183916001600160a01b03808716929088169160008051602061574783398151915291a450505050565b600081815260096020908152604080832054600b8352818420546001600160a01b03918216808652600c855283862088841680885295529285205492938085149392909116149060ff16828061305a5750815b806130625750805b979650505050505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152601354600090819087156131d7574287602001511180156130dd575060008760000151600f0b135b156131215786516130f29062eff100906154d6565b600f0b60208087019190915287015161310c90429061537d565b856020015161311b9190615514565b600f0b85525b42866020015111801561313b575060008660000151600f0b135b1561317f5785516131509062eff100906154d6565b600f0b60208086019190915286015161316a90429061537d565b84602001516131799190615514565b600f0b84525b602080880151600090815260148252604090205490870151600f9190910b9350156131d7578660200151866020015114156131bc578291506131d7565b602080870151600090815260149091526040902054600f0b91505b60408051608081018252600080825260208201524291810191909152436060820152811561324c575060008181526005602090815260409182902082516080810184528154600f81810b8352600160801b909104900b9281019290925260018101549282019290925260029091015460608201525b60408101518160004283101561329957604084015161326b904261537d565b606085015161327a904361537d565b61328c90670de0b6b3a76400006152b5565b61329691906152a1565b90505b600062093a806132a981866152a1565b6132b391906152b5565b905060005b60ff81101561342e576132ce62093a80836152d4565b91506000428311156132e2574292506132f6565b50600082815260146020526040902054600f0b5b613300868461537d565b876020015161330f9190615514565b8751889061331e9083906155a9565b600f0b9052506020870180518291906133389083906155f9565b600f90810b90915288516000910b1215905061335357600087525b60008760200151600f0b121561336b57600060208801525b60408088018490528501519295508592670de0b6b3a76400009061338f908561537d565b61339990866152b5565b6133a391906152a1565b85606001516133b291906152d4565b60608801526133c26001896152d4565b9750428314156133d8575043606087015261342e565b6000888152600560209081526040918290208951918a01516001600160801b03908116600160801b029216919091178155908801516001820155606088015160029091015550613427816152ec565b90506132b8565b505060138590558b156134b9578860200151886020015161344f91906155a9565b8460200181815161346091906155f9565b600f0b9052508851885161347491906155a9565b845185906134839083906155f9565b600f90810b90915260208601516000910b121590506134a457600060208501525b60008460000151600f0b12156134b957600084525b6000858152600560209081526040918290208651918701516001600160801b03908116600160801b02921691909117815590850151600182015560608501516002909101558b1561367c57428b60200151111561357157602089015161351f90886155f9565b96508a602001518a60200151141561354357602088015161354090886155a9565b96505b60208b810151600090815260149091526040902080546001600160801b0319166001600160801b0389161790555b428a6020015111156135cc578a602001518a6020015111156135cc57602088015161359c90876155a9565b60208b810151600090815260149091526040902080546001600160801b0319166001600160801b03831617905595505b60008c8152601060205260408120546135e69060016152d4565b905080601060008f815260200190815260200160002081905550428960400181815250504389606001818152505088601160008f815260200190815260200160002082633b9aca00811061363c5761363c615307565b825160208401516001600160801b03908116600160801b029116176003919091029190910190815560408201516001820155606090910151600290910155505b505050505050505050505050565b6136943382613007565b6136e05760405162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656460448201526064016111bd565b6000818152600960205260408120546001600160a01b0316906137039083610f63565b61371761370f82611895565b60008461430e565b613721338361428d565b60405182906000906001600160a01b03841690600080516020615747833981519152908390a45050565b60008281526010602052604081205480613769576000915050610f24565b600084815260116020526040812082633b9aca00811061378b5761378b615307565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b6020830152600181015492820183905260020154606082015291506137d79085615648565b81602001516137e69190615514565b815182906137f59083906155a9565b600f90810b90915282516000910b1215905061381057600081525b51600f0b9150610f249050565b600061382883611895565b6001600160a01b0384811660008181526018602052604080822080546001600160a01b031916888616908117909155905194955093928516927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46111478382846146ef565b60008261038f1415613a35576000546040516323b872dd60e01b815233600482015230602482015260448101869052620100009091046001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156138f357600080fd5b505af1158015613907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061392b9190615394565b6139655760405162461bcd60e51b815260206004820152600b60248201526a0e4c4c4e9a5b989bdd5b9960aa1b60448201526064016111bd565b60005460405163a9059cbb60e01b81526001600160a01b03848116600483015260248201879052620100009092049091169063a9059cbb90604401602060405180830381600087803b1580156139ba57600080fd5b505af11580156139ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139f29190615394565b613a2d5760405162461bcd60e51b815260206004820152600c60248201526b0e4c4c4e9bdd5d189bdd5b9960a21b60448201526064016111bd565b5060006115a1565b600854600160a81b900460ff16613a4b83612ee9565b1115613a695760405162461bcd60e51b81526004016111bd9061548c565b600062093a8080613a7a86426152d4565b613a8491906152a1565b613a8e91906152b5565b905060008511613a9d57600080fd5b428111613afb5760405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e207468652060448201526566757475726560d01b60648201526084016111bd565b613b0862eff100426152d4565b811115613b575760405162461bcd60e51b815260206004820152601f60248201527f566f74696e67206c6f636b2063616e206265203236207765656b73206d61780060448201526064016111bd565b600760008154613b66906152ec565b90915550600754613b778482614aab565b5060008181526012602090815260409182902082518084019093528054600f0b835260019081015491830191909152613bb591839189918691613f9d565b91506115a19050565b600080839050600062093a80808360400151613bda91906152a1565b613be491906152b5565b905060005b60ff811015613c9857613bff62093a80836152d4565b9150600085831115613c1357859250613c27565b50600082815260146020526040902054600f0b5b6040840151613c36908461537d565b8460200151613c459190615514565b84518590613c549083906155a9565b600f0b90525082861415613c685750613c98565b8084602001818151613c7a91906155f9565b600f0b9052505060408301829052613c91816152ec565b9050613be9565b5060008260000151600f0b1215613cae57600082525b50516001600160801b03169392505050565b600043821115613cd257613cd2615345565b600083815260106020526040812054815b6080811015613d7657818310613cf857613d76565b60006002613d0684866152d4565b613d119060016152d4565b613d1b91906152a1565b6000888152601160205260409020909150869082633b9aca008110613d4257613d42615307565b600302016002015411613d5757809350613d65565b613d6260018261537d565b92505b50613d6f816152ec565b9050613ce3565b50600085815260116020526040812083633b9aca008110613d9957613d99615307565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b602083015260018101549282019290925260029091015460608201526013549091506000613dee878361419c565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508084841015613ecd576000600581613e528760016152d4565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060808301829052860151919250613eaf919061537d565b925083604001518160400151613ec5919061537d565b915050613ef1565b6060830151613edc904361537d565b9150826040015142613eee919061537d565b90505b60408301518215613f2e578284606001518c613f0d919061537d565b613f1790846152b5565b613f2191906152a1565b613f2b90826152d4565b90505b6040870151613f3d908261537d565b8760200151613f4c9190615514565b87518890613f5b9083906155a9565b600f90810b90915288516000910b129050613f8b57505093516001600160801b03169650610f2495505050505050565b60009950505050505050505050610f24565b6015548290613fac86826152d4565b6015556040805180820190915260008082526020820152825160208085015190830152600f0b8152825187908490613fe59083906155f9565b600f0b9052508515613ff957602083018690525b6000888152601260209081526040909120845181546001600160801b0319166001600160801b039091161781559084015160019091015561403b88828561306d565b33871580159061405d5750600485600481111561405a5761405a615687565b14155b15614101576000546040516323b872dd60e01b81526001600160a01b038381166004830152306024830152604482018b905262010000909204909116906323b872dd90606401602060405180830381600087803b1580156140bd57600080fd5b505af11580156140d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140f59190615394565b61410157614101615345565b8360200151816001600160a01b03167fff04ccafc360e16b67d682d17bd9503c4c6b9a131f6be6325762dc9ffc7de6248b8b8942604051614145949392919061569d565b60405180910390a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c836141798a826152d4565b6040805192835260208301919091520160405180910390a1505050505050505050565b60008082815b608081101561421c578183106141b75761421c565b600060026141c584866152d4565b6141d09060016152d4565b6141da91906152a1565b60008181526005602052604090206002015490915087106141fd5780935061420b565b61420860018261537d565b92505b50614215816152ec565b90506141a2565b5090949350505050565b6000818152600960205260409020546001600160a01b0383811691161461424f5761424f615345565b6000818152600b60205260409020546001600160a01b031615614289576000818152600b6020526040902080546001600160a01b03191690555b5050565b6000818152600960205260409020546001600160a01b038381169116146142b6576142b6615345565b600081815260096020526040902080546001600160a01b03191690556142dc8282614b0a565b6001600160a01b0382166000908152600a6020526040812080546001929061430590849061537d565b90915550505050565b816001600160a01b0316836001600160a01b0316141580156143305750600081115b15611147576001600160a01b038316156144b1576001600160a01b0383166000908152601b602052604081205463ffffffff169081614394576001600160a01b0385166000908152601a6020908152604080832083805290915290206001016143d6565b6001600160a01b0385166000908152601a60205260408120906143b8600185615243565b63ffffffff1663ffffffff1681526020019081526020016000206001015b905060006143e386614bbc565b6001600160a01b0387166000908152601a6020908152604080832063ffffffff8516845290915281209192506001909101905b835481101561447057600084828154811061443357614433615307565b9060005260206000200154905086811461445d578254600181018455600084815260209020018190555b5080614468816152ec565b915050614416565b5061447c8460016156db565b6001600160a01b0388166000908152601b60205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03821615611147576001600160a01b0382166000908152601b602052604081205463ffffffff169081614510576001600160a01b0384166000908152601a602090815260408083208380529091529020600101614552565b6001600160a01b0384166000908152601a6020526040812090614534600185615243565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061455f85614bbc565b6001600160a01b0386166000908152601a6020908152604080832063ffffffff8516845290915290208354919250600190810191610400916145a191906152d4565b11156145bf5760405162461bcd60e51b81526004016111bd90615703565b60005b83548110156146115760008482815481106145df576145df615307565b600091825260208083209091015485546001810187558684529190922001555080614609816152ec565b9150506145c2565b508054600181810183556000838152602090209091018690556146359085906156db565b6001600160a01b0387166000908152601b60205260409020805463ffffffff9290921663ffffffff1990921691909117905550505050505050565b6000818152600960205260409020546001600160a01b03161561469557614695615345565b600081815260096020526040902080546001600160a01b0319166001600160a01b0384161790556146c68282614c35565b6001600160a01b0382166000908152600a602052604081208054600192906143059084906152d4565b806001600160a01b0316826001600160a01b031614611147576001600160a01b038216156148a2576001600160a01b0382166000908152601b602052604081205463ffffffff169081614767576001600160a01b0384166000908152601a6020908152604080832083805290915290206001016147a9565b6001600160a01b0384166000908152601a602052604081209061478b600185615243565b63ffffffff1663ffffffff1681526020019081526020016000206001015b905060006147b685614bbc565b6001600160a01b0386166000908152601a6020908152604080832063ffffffff8516845290915281209192506001909101905b835481101561486157600084828154811061480657614806615307565b600091825260208083209091015480835260099091526040909120549091506001600160a01b03908116908a161461484e578254600181018455600084815260209020018190555b5080614859816152ec565b9150506147e9565b5061486d8460016156db565b6001600160a01b0387166000908152601b60205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03811615611147576001600160a01b0381166000908152601b602052604081205463ffffffff169081614901576001600160a01b0383166000908152601a602090815260408083208380529091529020600101614943565b6001600160a01b0383166000908152601a6020526040812090614925600185615243565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061495084614bbc565b6001600160a01b038086166000908152601a6020908152604080832063ffffffff861684528252808320938b168352600a9091529020548454929350600190910191610400906149a19083906152d4565b11156149bf5760405162461bcd60e51b81526004016111bd90615703565b60005b8454811015614a115760008582815481106149df576149df615307565b600091825260208083209091015486546001810188558784529190922001555080614a09816152ec565b9150506149c2565b5060005b81811015614a63576001600160a01b0389166000908152600e602090815260408083208484528252822054855460018101875586845291909220015580614a5b816152ec565b915050614a15565b50614a6f8560016156db565b6001600160a01b0387166000908152601b60205260409020805463ffffffff9290921663ffffffff199092169190911790555050505050505050565b60006001600160a01b038316614ac357614ac3615345565b614ad16000612fbb85611895565b614adb8383614670565b60405182906001600160a01b03851690600090600080516020615747833981519152908290a450600192915050565b60006001614b1784612ee9565b614b21919061537d565b6000838152600f602052604090205490915080821415614b71576001600160a01b0384166000908152600e602090815260408083208584528252808320839055858352600f9091528120556124f5565b6001600160a01b03939093166000908152600e6020908152604080832093835292815282822080548684528484208190558352600f9091528282209490945592839055908252812055565b6001600160a01b0381166000908152601b6020526040812054429063ffffffff168015801590614c2557506001600160a01b0384166000908152601a602052604081208391614c0c600185615243565b63ffffffff168152602081019190915260400160002054145b156115a157611a2c600182615243565b6000614c4083612ee9565b6001600160a01b039093166000908152600e602090815260408083208684528252808320859055938252600f9052919091209190915550565b6001600160e01b03198116811461192d57600080fd5b600060208284031215614ca157600080fd5b81356115a181614c79565b60005b83811015614cc7578181015183820152602001614caf565b838111156124f55750506000910152565b60008151808452614cf0816020860160208601614cac565b601f01601f19169290920160200192915050565b6020815260006115a16020830184614cd8565b80356001600160a01b0381168114614d2e57600080fd5b919050565b60008060408385031215614d4657600080fd5b614d4f83614d17565b946020939093013593505050565b600060208284031215614d6f57600080fd5b5035919050565b600060208284031215614d8857600080fd5b6115a182614d17565b60008060408385031215614da457600080fd5b50508035926020909101359150565b600080600060608486031215614dc857600080fd5b614dd184614d17565b9250614ddf60208501614d17565b9150604084013590509250925092565b60008060408385031215614e0257600080fd5b614e0b83614d17565b9150614e1960208401614d17565b90509250929050565b803560ff81168114614d2e57600080fd5b600060208284031215614e4557600080fd5b6115a182614e22565b6020808252825182820181905260009190848201906040850190845b81811015614e8657835183529284019291840191600101614e6a565b50909695505050505050565b801515811461192d57600080fd5b60008060408385031215614eb357600080fd5b614ebc83614d17565b91506020830135614ecc81614e92565b809150509250929050565b600060208284031215614ee957600080fd5b81356115a181614e92565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614f3357614f33614ef4565b604052919050565b600067ffffffffffffffff821115614f5557614f55614ef4565b50601f01601f191660200190565b60008060008060808587031215614f7957600080fd5b614f8285614d17565b9350614f9060208601614d17565b925060408501359150606085013567ffffffffffffffff811115614fb357600080fd5b8501601f81018713614fc457600080fd5b8035614fd7614fd282614f3b565b614f0a565b818152886020838501011115614fec57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060008060008060c0878903121561502757600080fd5b61503087614d17565b9550602087013594506040870135935061504c60608801614e22565b92506080870135915060a087013590509295509295509295565b6000602080838503121561507957600080fd5b823567ffffffffffffffff8082111561509157600080fd5b818501915085601f8301126150a557600080fd5b8135818111156150b7576150b7614ef4565b8060051b91506150c8848301614f0a565b81815291830184019184810190888411156150e257600080fd5b938501935b83851015615100578435825293850193908501906150e7565b98975050505050505050565b60008060006060848603121561512157600080fd5b833592506020840135915061513860408501614d17565b90509250925092565b6000806040838503121561515457600080fd5b61515d83614d17565b9150602083013563ffffffff81168114614ecc57600080fd5b60006020828403121561518857600080fd5b815167ffffffffffffffff81111561519f57600080fd5b8201601f810184136151b057600080fd5b80516151be614fd282614f3b565b8181528560208385010111156151d357600080fd5b6151e4826020830160208601614cac565b95945050505050565b600082516151ff818460208701614cac565b6e0102b37ba34b7339022b9b1b937bb9608d1b920191825250630f09f94960e41b600f820152601301919050565b634e487b7160e01b600052601160045260246000fd5b600063ffffffff838116908316818110156152605761526061522d565b039392505050565b634e487b7160e01b600052601260045260246000fd5b600063ffffffff8084168061529557615295615268565b92169190910492915050565b6000826152b0576152b0615268565b500490565b60008160001904831182151516156152cf576152cf61522d565b500290565b600082198211156152e7576152e761522d565b500190565b60006000198214156153005761530061522d565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252600e908201526d4e6f2072652d656e7472616e637960901b604082015260600190565b634e487b7160e01b600052600160045260246000fd5b602080825260089082015267185d1d1858da195960c21b604082015260600190565b60008282101561538f5761538f61522d565b500390565b6000602082840312156153a657600080fd5b81516115a181614e92565b602080825260039082015262216d7360e81b604082015260600190565b61766560f01b8152600082516153eb816002850160208701614cac565b9190910160020192915050565b60208082526024908201527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686040820152636472617760e01b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611ee690830184614cd8565b60006020828403121561548157600080fd5b81516115a181614c79565b6020808252602a908201527f45786365656473204d6178204e465420486f6c64696e67204c696d69742070656040820152697220616464726573732160b01b606082015260800190565b600081600f0b83600f0b806154ed576154ed615268565b60016001607f1b031982146000198214161561550b5761550b61522d565b90059392505050565b600081600f0b83600f0b60016001607f1b036000821360008413838304851182821616156155445761554461522d565b60016001607f1b031960008512828116878305871216156155675761556761522d565b600087129250858205871284841616156155835761558361522d565b858505871281841616156155995761559961522d565b5050509290910295945050505050565b600081600f0b83600f0b600081128160016001607f1b0319018312811516156155d4576155d461522d565b8160016001607f1b030183138116156155ef576155ef61522d565b5090039392505050565b600081600f0b83600f0b600082128260016001607f1b03038213811516156156235761562361522d565b8260016001607f1b031903821281161561563f5761563f61522d565b50019392505050565b60008083128015600160ff1b8501841216156156665761566661522d565b6001600160ff1b03840183138116156156815761568161522d565b50500390565b634e487b7160e01b600052602160045260246000fd5b8481526020810184905260808101600584106156c957634e487b7160e01b600052602160045260246000fd5b60408201939093526060015292915050565b600063ffffffff8083168185168083038211156156fa576156fa61522d565b01949350505050565b60208082526023908201527f64737452657020776f756c64206861766520746f6f206d616e7920746f6b656e60408201526249647360e81b60608201526080019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220d2ffb784f3a3c51df6bf36e0bcac00d5ba3249877112db76334fc59a2a2f92bd64736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104c25760003560e01c80638462151c11610278578063c1f0fb9f1161015c578063e441135c116100ce578063f096636811610092578063f096636814610c6f578063f1127ed814610c7c578063f8a0576314610ca7578063fbd3a29d14610cca578063fc0c546a14610cdd578063fd4a77f114610cf657600080fd5b8063e441135c14610bc6578063e7a324dc14610be6578063e7e242d414610c0d578063e985e9c514610c20578063ee99fe2814610c5c57600080fd5b8063d157e30111610120578063d157e30114610b3f578063d1c2babb14610b47578063d1febfb914610b5a578063d4e54c3b14610b98578063d826f88f14610bab578063e0514aba14610bb357600080fd5b8063c1f0fb9f14610aeb578063c2c4c5c114610afe578063c3cda52014610b06578063c568d48014610b19578063c87b56dd14610b2c57600080fd5b8063986b7d8a116101f5578063a2ee4a7c116101b9578063a2ee4a7c14610a3e578063a4d855df14610a52578063aab8015814610a65578063b45a3c0e14610a78578063b88d4fde14610ac0578063b94ef2b814610ad357600080fd5b8063986b7d8a146109df5780639ab24eb0146109f2578063a0b2d57f14610a05578063a183af5214610a18578063a22cb46514610a2b57600080fd5b8063900cf0cf1161023c578063900cf0cf146109955780639506ec8e1461099e57806395d89b41146109b15780639624d163146109b9578063981b24d0146109cc57600080fd5b80638462151c1461091957806385f2aef2146109395780638c2c9baf1461094c5780638e539e8c1461095f5780638fbb38ff1461097257600080fd5b806342842e0e116103aa57806362af40731161031c57806370a08231116102e057806370a08231146108a05780637116c60c146108b357806371197484146108c65780637d549e99146108e95780637e1c0c09146108f15780637ecebe00146108f957600080fd5b806362af40731461080b5780636352211e1461081e57806365fc3873146108475780636f5488371461085a5780636fcfff451461087a57600080fd5b80634bc2a6571161036e5780634bc2a6571461079257806354fd4d50146107a55780635594a045146107c9578063587cde1e146107dc5780635c19a95c146107ef5780635f5b0c321461080257600080fd5b806342842e0e14610720578063430c208114610733578063461f711c1461074657806346c96aac1461076c578063485cc9551461077f57600080fd5b806318160ddd116104435780632e1a7d4d116104075780632e1a7d4d146106845780632e720f7d146106975780632f745c59146106aa578063313ce567146106e05780633a46b1a8146106fa5780633b1e371f1461070d57600080fd5b806318160ddd146106295780631c984bc31461063157806320606b701461064457806323b872dd1461066b57806325a58b561461067e57600080fd5b8063095cf5c61161048a578063095cf5c61461059e578063095ea7b3146105b35780630d6a2033146105c65780631376f3da146105e657806314a3c8c31461062157600080fd5b806301ffc9a7146104c7578063047fc9aa1461050957806306fdde03146105205780630758c7d814610535578063081812fc1461055d575b600080fd5b6104f46104d5366004614c8f565b6001600160e01b03191660009081526006602052604090205460ff1690565b60405190151581526020015b60405180910390f35b61051260155481565b604051908152602001610500565b610528610d09565b6040516105009190614d04565b610548610543366004614d33565b610db9565b60405163ffffffff9091168152602001610500565b61058661056b366004614d5d565b6000908152600b60205260409020546001600160a01b031690565b6040516001600160a01b039091168152602001610500565b6105b16105ac366004614d76565b610f2a565b005b6105b16105c1366004614d33565b610f63565b6105126105d4366004614d5d565b60166020526000908152604090205481565b6105f96105f4366004614d91565b61104c565b60408051600f95860b81529390940b6020840152928201526060810191909152608001610500565b6105b1611093565b61051261114c565b61051261063f366004614d91565b61115c565b6105127f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6105b1610679366004614db3565b61118e565b43610512565b6105b1610692366004614d5d565b61119a565b6105b16106a5366004614d76565b611456565b6105126106b8366004614d33565b6001600160a01b03919091166000908152600e60209081526040808320938352929052205490565b6106e8601281565b60405160ff9091168152602001610500565b610512610708366004614d33565b61148f565b6105b161071b366004614d76565b61152e565b6105b161072e366004614db3565b61157a565b6104f4610741366004614d33565b611595565b610759610754366004614d5d565b6115a8565b604051600f9190910b8152602001610500565b600154610586906001600160a01b031681565b6105b161078d366004614def565b6115eb565b6105b16107a0366004614d76565b61187e565b610528604051806040016040528060058152602001640332e302e360dc1b81525081565b600454610586906001600160a01b031681565b6105866107ea366004614d76565b611895565b6105b16107fd366004614d76565b6118c5565b61051261040081565b6105b1610819366004614e33565b611930565b61058661082c366004614d5d565b6000908152600960205260409020546001600160a01b031690565b610512610855366004614d91565b61197a565b610512610868366004614d5d565b600d6020526000908152604090205481565b610548610888366004614d76565b601b6020526000908152604090205463ffffffff1681565b6105126108ae366004614d76565b6119c9565b6105126108c1366004614d5d565b6119d4565b6107596108d4366004614d5d565b601460205260009081526040902054600f0b81565b600754610512565b610512611a34565b610512610907366004614d76565b601c6020526000908152604090205481565b61092c610927366004614d76565b611a4d565b6040516105009190614e4e565b600254610586906001600160a01b031681565b61051261095a366004614d91565b611b0b565b61051261096d366004614d5d565b611b17565b6104f4610980366004614d5d565b60176020526000908152604090205460ff1681565b61051260135481565b6105b16109ac366004614d76565b611b22565b610528611b74565b6105b16109c7366004614d91565b611c10565b6105126109da366004614d5d565b611d4e565b6105b16109ed366004614d5d565b611ef0565b610512610a00366004614d76565b611f85565b600354610586906001600160a01b031681565b6105b1610a26366004614d91565b612056565b6105b1610a39366004614ea0565b61209c565b6008546106e890600160a81b900460ff1681565b6105b1610a60366004614d91565b612121565b6105b1610a73366004614ed7565b612313565b610aa6610a86366004614d5d565b60126020526000908152604090208054600190910154600f9190910b9082565b60408051600f9390930b8352602083019190915201610500565b6105b1610ace366004614f63565b612350565b6008546105869061010090046001600160a01b031681565b6105b1610af9366004614d5d565b6124fb565b6105b161252a565b6105b1610b1436600461500e565b61256a565b6105b1610b27366004615066565b6128d3565b610528610b3a366004614d5d565b612997565b610512612ad2565b6105b1610b55366004614d91565b612ade565b6105f9610b68366004614d5d565b600560205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b610512610ba636600461510c565b612c44565b6105b1612c94565b610512610bc1366004614d91565b612ce2565b610512610bd4366004614d5d565b60106020526000908152604090205481565b6105127fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b610512610c1b366004614d5d565b612cee565b6104f4610c2e366004614def565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b6105b1610c6a366004614d91565b612d16565b6019546104f49060ff1681565b610512610c8a366004615141565b601a60209081526000928352604080842090915290825290205481565b610512610cb5366004614d5d565b60009081526012602052604090206001015490565b6105b1610cd8366004614d5d565b612e35565b600054610586906201000090046001600160a01b031681565b6105b1610d04366004614d5d565b612eb7565b6060600060029054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015610d5957600080fd5b505afa158015610d6d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d959190810190615176565b604051602001610da591906151ed565b604051602081830303815290604052905090565b6001600160a01b0382166000908152601b602052604081205463ffffffff1680610de7576000915050610f24565b6001600160a01b0384166000908152601a602052604081208491610e0c600185615243565b63ffffffff16815260208101919091526040016000205411610e3b57610e33600182615243565b915050610f24565b6001600160a01b0384166000908152601a60209081526040808320838052909152902054831015610e70576000915050610f24565b600080610e7e600184615243565b90505b8163ffffffff168163ffffffff161115610f1f5760006002610ea38484615243565b610ead919061527e565b610eb79083615243565b6001600160a01b0388166000908152601a6020908152604080832063ffffffff851684529091529020805491925090871415610ef957509350610f2492505050565b8054871115610f0a57819350610f18565b610f15600183615243565b92505b5050610e81565b509150505b92915050565b6002546001600160a01b03163314610f4157600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600960205260409020546001600160a01b031680610f8557600080fd5b806001600160a01b0316836001600160a01b03161415610fa457600080fd5b6000828152600960209081526040808320546001600160a01b038581168552600c845282852033808752945291909320549216149060ff168180610fe55750805b610fee57600080fd5b6000848152600b602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a45050505050565b601160205281600052604060002081633b9aca00811061106b57600080fd5b6003020180546001820154600290920154600f82810b9550600160801b90920490910b925084565b600061109e33612ee9565b9050600062eff10062093a806110b481426152a1565b6110be91906152b5565b6110c891906152d4565b905060005b8281101561114757336000908152600e60209081526040808320848452825280832054808452601290925282206001015490919062093a80906111119082906152a1565b61111b91906152b5565b905083811015611132576111328262eff100612121565b5050808061113f906152ec565b9150506110cd565b505050565b6000611157426119d4565b905090565b600082815260116020526040812082633b9aca00811061117e5761117e615307565b6003020160010154905092915050565b61114783838333612f04565b60085460ff16156111c65760405162461bcd60e51b81526004016111bd9061531d565b60405180910390fd5b6008805460ff191660011790556111dd3382613007565b6111e9576111e9615345565b600081815260166020526040902054158015611214575060008181526017602052604090205460ff16155b6112305760405162461bcd60e51b81526004016111bd9061535b565b60008181526012602090815260409182902082518084019093528054600f0b8352600101549082018190524210156112a35760405162461bcd60e51b8152602060048201526016602482015275546865206c6f636b206469646e27742065787069726560501b60448201526064016111bd565b8051604080518082018252600080825260208083018281528783526012909152929020905181546001600160801b0319166001600160801b039091161781559051600190910155601554600f9190910b906112fe828261537d565b6015556040805180820190915260008082526020820152611322908590859061306d565b60005460405163a9059cbb60e01b815233600482015260248101849052620100009091046001600160a01b03169063a9059cbb90604401602060405180830381600087803b15801561137357600080fd5b505af1158015611387573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ab9190615394565b6113b7576113b7615345565b6113c08461368a565b60408051858152602081018490524281830152905133917f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94919081900360600190a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c8161142e848261537d565b6040805192835260208301919091520160405180910390a150506008805460ff191690555050565b6002546001600160a01b0316331461146d57600080fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60008061149c8484610db9565b6001600160a01b0385166000908152601a6020908152604080832063ffffffff851684529091528120919250600190910190805b82548110156115245760008382815481106114ed576114ed615307565b90600052602060002001549050611504818861374b565b61150e90846152d4565b925050808061151c906152ec565b9150506114d0565b5095945050505050565b6003546001600160a01b031633146115585760405162461bcd60e51b81526004016111bd906153b1565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b61114783838360405180602001604052806000815250612350565b60006115a18383613007565b9392505050565b6000818152601060209081526040808320546011909252822081633b9aca0081106115d5576115d5615307565b6003020154600160801b9004600f0b9392505050565b600054610100900460ff161580801561160b5750600054600160ff909116105b806116255750303b158015611625575060005460ff166001145b6116885760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016111bd565b6000805460ff1916600117905580156116ab576000805461ff0019166101001790555b6000805462010000600160b01b031916620100006001600160a01b038681169190910291909117825560018054336001600160a01b03199182168117835560028054831682179055600380548316909117905560048054909116928616929092179091556008805460ff60a81b1916600560aa1b179055437f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746be55427f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bd5560066020527f477a984de5936bcb02475f64e0ea676103106ac0785c67bf7e9e846450b51ef6805460ff1990811683179091557fd544553a2e70858ffdf1e1169f6f124859d29ddf2686bcabf4e6f71bc63044228054821683179055635b5e139f60e01b83527fcc41b8fe3dd37df8e4a56c49f4e83a8fb6899f1fe8f1ddc40678281e8ec622128054909116909117905560075460405190913091600080516020615747833981519152908290a46007546040516000903090600080516020615747833981519152908390a48015611147576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6001546001600160a01b0316331461155857600080fd5b6001600160a01b0380821660009081526018602052604081205490911680156118be57806115a1565b5090919050565b60195460ff166119125760405162461bcd60e51b815260206004820152601860248201527744656c65676174696f6e73204e6f7420416c6c6f7765642160401b60448201526064016111bd565b6001600160a01b0381166119235750335b61192d338261381d565b50565b6003546001600160a01b0316331461195a5760405162461bcd60e51b81526004016111bd906153b1565b6008805460ff909216600160a81b0260ff60a81b19909216919091179055565b60085460009060ff16156119a05760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff191660011790556119b8838333613890565b6008805460ff191690559392505050565b6000610f2482612ee9565b601354600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060820152909190611a2c8185613bbe565b949350505050565b6000611a406000612ee9565b600754611157919061537d565b60606000611a5a83612ee9565b905060008167ffffffffffffffff811115611a7757611a77614ef4565b604051908082528060200260200182016040528015611aa0578160200160208202803683370190505b50905060005b82811015611b03576001600160a01b0385166000908152600e602090815260408083208484529091529020548251839083908110611ae657611ae6615307565b602090810291909101015280611afb816152ec565b915050611aa6565b509392505050565b60006115a18383613cc0565b6000610f24826119d4565b6003546001600160a01b03163314611b4c5760405162461bcd60e51b81526004016111bd906153b1565b600880546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6060600060029054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015611bc457600080fd5b505afa158015611bd8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c009190810190615176565b604051602001610da591906153ce565b60085460ff1615611c335760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff19166001179055600254336001600160a01b0390911614611c875760405162461bcd60e51b81526020600482015260086024820152676e6f74207465616d60c01b60448201526064016111bd565b60008281526012602090815260409182902082518084019093528054600f0b8352600101549082015281611cbd57611cbd615345565b60008160000151600f0b13611d0d5760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b60448201526064016111bd565b42816020015111611d305760405162461bcd60e51b81526004016111bd906153f8565b611d3f83836000846002613f9d565b50506008805460ff1916905550565b600043821115611d6057611d60615345565b6013546000611d6f848361419c565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606082015291925083831015611e7e576000600581611dd28660016152d4565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905285015191925014611e785782606001518160600151611e3e919061537d565b83604001518260400151611e52919061537d565b6060850151611e61908a61537d565b611e6b91906152b5565b611e7591906152a1565b91505b50611ecd565b43826060015114611ecd576060820151611e98904361537d565b6040830151611ea7904261537d565b6060840151611eb6908961537d565b611ec091906152b5565b611eca91906152a1565b90505b611ee682828460400151611ee191906152d4565b613bbe565b9695505050505050565b60085461010090046001600160a01b0316331480611f1857506001546001600160a01b031633145b611f585760405162461bcd60e51b81526020600482015260116024820152702737ba1037b63217b7b632102b37ba32b960791b60448201526064016111bd565b600081815260166020526040902054611f739060019061537d565b60009182526016602052604090912055565b6001600160a01b0381166000908152601b602052604081205463ffffffff1680611fb25750600092915050565b6001600160a01b0383166000908152601a6020526040812081611fd6600185615243565b63ffffffff1663ffffffff16815260200190815260200160002060010190506000805b825481101561204d57600083828154811061201657612016615307565b9060005260206000200154905061202d814261374b565b61203790846152d4565b9250508080612045906152ec565b915050611ff9565b50949350505050565b60085460ff16156120795760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff191660011790556120903383613007565b611c8757611c87615345565b6001600160a01b0382163314156120b5576120b5615345565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60085460ff16156121445760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff1916600117905561215b3383613007565b61216757612167615345565b600082815260126020908152604080832081518083019092528054600f0b825260010154918101919091529062093a80806121a285426152d4565b6121ac91906152a1565b6121b691906152b5565b9050428260200151116121fa5760405162461bcd60e51b815260206004820152600c60248201526b131bd8dac8195e1c1a5c995960a21b60448201526064016111bd565b60008260000151600f0b136122455760405162461bcd60e51b8152602060048201526011602482015270139bdd1a1a5b99c81a5cc81b1bd8dad959607a1b60448201526064016111bd565b816020015181116122985760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e0060448201526064016111bd565b6122a562eff100426152d4565b8111156122f45760405162461bcd60e51b815260206004820152601f60248201527f566f74696e67206c6f636b2063616e206265203236207765656b73206d61780060448201526064016111bd565b61230384600083856003613f9d565b50506008805460ff191690555050565b6003546001600160a01b0316331461233d5760405162461bcd60e51b81526004016111bd906153b1565b6019805460ff1916911515919091179055565b61235c84848433612f04565b823b156124f557604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061239590339088908790879060040161543c565b602060405180830381600087803b1580156123af57600080fd5b505af19250505080156123df575060408051601f3d908101601f191682019092526123dc9181019061546f565b60015b612484573d80801561240d576040519150601f19603f3d011682016040523d82523d6000602084013e612412565b606091505b50805161247c5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016111bd565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146124f35760405162461bcd60e51b815260206004820152602660248201527f4552433732313a2045524337323152656365697665722072656a656374656420604482015265746f6b656e7360d01b60648201526084016111bd565b505b50505050565b6001546001600160a01b0316331461251257600080fd5b6000908152601760205260409020805460ff19169055565b612568600060405180604001604052806000600f0b8152602001600081525060405180604001604052806000600f0b8152602001600081525061306d565b565b60195460ff166125b75760405162461bcd60e51b815260206004820152601860248201527744656c65676174696f6e73204e6f7420416c6c6f7765642160401b60448201526064016111bd565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8666125e2610d09565b805160209182012060408051808201825260058152640332e302e360dc1b90840152805180840194909452838101919091527fd7a1ce683065975771bedf401ecab037f4f4c62cc51fefdc8b39dd246ff0343a60608401524660808401523060a0808501919091528151808503909101815260c0840182528051908301207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60e08501526001600160a01b038b1661010085015261012084018a90526101408085018a90528251808603909101815261016085019092528151919092012061190160f01b61018084015261018283018290526101a28301819052909250906000906101c20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015612752573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166127cc5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e7660448201526d616c6964207369676e617475726560901b60648201526084016111bd565b6001600160a01b0381166000908152601c602052604081208054916127f0836152ec565b9190505589146128555760405162461bcd60e51b815260206004820152602a60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a20696e76604482015269616c6964206e6f6e636560b01b60648201526084016111bd565b874211156128bc5760405162461bcd60e51b815260206004820152602e60248201527f566f74696e67457363726f773a3a64656c656761746542795369673a2073696760448201526d1b985d1d5c9948195e1c1a5c995960921b60648201526084016111bd565b6128c6818b61381d565b505050505b505050505050565b600062eff10062093a806128e781426152a1565b6128f191906152b5565b6128fb91906152d4565b905060005b825181101561114757600062093a80806012600087868151811061292657612926615307565b602002602001015181526020019081526020016000206001015461294a91906152a1565b61295491906152b5565b9050828110156129845761298484838151811061297357612973615307565b602002602001015162eff100612121565b508061298f816152ec565b915050612900565b6000818152600960205260409020546060906001600160a01b03166129fe5760405162461bcd60e51b815260206004820152601b60248201527f517565727920666f72206e6f6e6578697374656e7420746f6b656e000000000060448201526064016111bd565b60008281526012602090815260409182902082518084019093528054600f0b835260010154908201526004546001600160a01b031663dd9ec14984612a43814261374b565b6020850151855160405160e086901b6001600160e01b0319168152600481019490945260248401929092526044830152600f0b606482015260840160006040518083038186803b158015612a9657600080fd5b505afa158015612aaa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115a19190810190615176565b60006111576000612ee9565b600082815260166020526040902054158015612b09575060008281526017602052604090205460ff16155b612b255760405162461bcd60e51b81526004016111bd9061535b565b80821415612b3257600080fd5b612b3c3383613007565b612b4557600080fd5b612b4f3382613007565b612b5857600080fd5b6000828152601260208181526040808420815180830183528154600f90810b825260019283015482860190815288885295855283872084518086019095528054820b855290920154938301849052805194519095929490910b921115612bc2578260200151612bc8565b83602001515b604080518082018252600080825260208083018281528b835260128252848320935184546001600160801b0319166001600160801b0390911617845551600190930192909255825180840190935280835290820152909150612c2d908790869061306d565b612c368661368a565b6128cb858383866004613f9d565b60085460009060ff1615612c6a5760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff19166001179055612c82848484613890565b6008805460ff19169055949350505050565b6003546001600160a01b03163314612cbe5760405162461bcd60e51b81526004016111bd906153b1565b600354600280546001600160a01b0319166001600160a01b03909216919091179055565b60006115a1838361374b565b6000818152600d6020526040812054431415612d0c57506000919050565b610f24824261374b565b60085460ff1615612d395760405162461bcd60e51b81526004016111bd9061531d565b6008805460ff1916600190811790915560008381526012602090815260409182902082518084019093528054600f0b8352909201549181019190915281612db35760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016111bd565b60008160000151600f0b13612e035760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b60448201526064016111bd565b42816020015111612e265760405162461bcd60e51b81526004016111bd906153f8565b611d3f83836000846000613f9d565b60085461010090046001600160a01b0316331480612e5d57506001546001600160a01b031633145b612e9d5760405162461bcd60e51b81526020600482015260116024820152702737ba1037b63217b7b632102b37ba32b960791b60448201526064016111bd565b600081815260166020526040902054611f739060016152d4565b6001546001600160a01b03163314612ece57600080fd5b6000908152601760205260409020805460ff19166001179055565b6001600160a01b03166000908152600a602052604090205490565b600082815260166020526040902054158015612f2f575060008281526017602052604090205460ff16155b612f4b5760405162461bcd60e51b81526004016111bd9061535b565b600854600160a81b900460ff16612f6184612ee9565b1115612f7f5760405162461bcd60e51b81526004016111bd9061548c565b612f898183613007565b612f9257600080fd5b612f9c8483614226565b612fa6848361428d565b612fc1612fb285611895565b612fbb85611895565b8461430e565b612fcb8383614670565b6000828152600d60205260408082204390555183916001600160a01b03808716929088169160008051602061574783398151915291a450505050565b600081815260096020908152604080832054600b8352818420546001600160a01b03918216808652600c855283862088841680885295529285205492938085149392909116149060ff16828061305a5750815b806130625750805b979650505050505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152601354600090819087156131d7574287602001511180156130dd575060008760000151600f0b135b156131215786516130f29062eff100906154d6565b600f0b60208087019190915287015161310c90429061537d565b856020015161311b9190615514565b600f0b85525b42866020015111801561313b575060008660000151600f0b135b1561317f5785516131509062eff100906154d6565b600f0b60208086019190915286015161316a90429061537d565b84602001516131799190615514565b600f0b84525b602080880151600090815260148252604090205490870151600f9190910b9350156131d7578660200151866020015114156131bc578291506131d7565b602080870151600090815260149091526040902054600f0b91505b60408051608081018252600080825260208201524291810191909152436060820152811561324c575060008181526005602090815260409182902082516080810184528154600f81810b8352600160801b909104900b9281019290925260018101549282019290925260029091015460608201525b60408101518160004283101561329957604084015161326b904261537d565b606085015161327a904361537d565b61328c90670de0b6b3a76400006152b5565b61329691906152a1565b90505b600062093a806132a981866152a1565b6132b391906152b5565b905060005b60ff81101561342e576132ce62093a80836152d4565b91506000428311156132e2574292506132f6565b50600082815260146020526040902054600f0b5b613300868461537d565b876020015161330f9190615514565b8751889061331e9083906155a9565b600f0b9052506020870180518291906133389083906155f9565b600f90810b90915288516000910b1215905061335357600087525b60008760200151600f0b121561336b57600060208801525b60408088018490528501519295508592670de0b6b3a76400009061338f908561537d565b61339990866152b5565b6133a391906152a1565b85606001516133b291906152d4565b60608801526133c26001896152d4565b9750428314156133d8575043606087015261342e565b6000888152600560209081526040918290208951918a01516001600160801b03908116600160801b029216919091178155908801516001820155606088015160029091015550613427816152ec565b90506132b8565b505060138590558b156134b9578860200151886020015161344f91906155a9565b8460200181815161346091906155f9565b600f0b9052508851885161347491906155a9565b845185906134839083906155f9565b600f90810b90915260208601516000910b121590506134a457600060208501525b60008460000151600f0b12156134b957600084525b6000858152600560209081526040918290208651918701516001600160801b03908116600160801b02921691909117815590850151600182015560608501516002909101558b1561367c57428b60200151111561357157602089015161351f90886155f9565b96508a602001518a60200151141561354357602088015161354090886155a9565b96505b60208b810151600090815260149091526040902080546001600160801b0319166001600160801b0389161790555b428a6020015111156135cc578a602001518a6020015111156135cc57602088015161359c90876155a9565b60208b810151600090815260149091526040902080546001600160801b0319166001600160801b03831617905595505b60008c8152601060205260408120546135e69060016152d4565b905080601060008f815260200190815260200160002081905550428960400181815250504389606001818152505088601160008f815260200190815260200160002082633b9aca00811061363c5761363c615307565b825160208401516001600160801b03908116600160801b029116176003919091029190910190815560408201516001820155606090910151600290910155505b505050505050505050505050565b6136943382613007565b6136e05760405162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656460448201526064016111bd565b6000818152600960205260408120546001600160a01b0316906137039083610f63565b61371761370f82611895565b60008461430e565b613721338361428d565b60405182906000906001600160a01b03841690600080516020615747833981519152908390a45050565b60008281526010602052604081205480613769576000915050610f24565b600084815260116020526040812082633b9aca00811061378b5761378b615307565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b6020830152600181015492820183905260020154606082015291506137d79085615648565b81602001516137e69190615514565b815182906137f59083906155a9565b600f90810b90915282516000910b1215905061381057600081525b51600f0b9150610f249050565b600061382883611895565b6001600160a01b0384811660008181526018602052604080822080546001600160a01b031916888616908117909155905194955093928516927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46111478382846146ef565b60008261038f1415613a35576000546040516323b872dd60e01b815233600482015230602482015260448101869052620100009091046001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156138f357600080fd5b505af1158015613907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061392b9190615394565b6139655760405162461bcd60e51b815260206004820152600b60248201526a0e4c4c4e9a5b989bdd5b9960aa1b60448201526064016111bd565b60005460405163a9059cbb60e01b81526001600160a01b03848116600483015260248201879052620100009092049091169063a9059cbb90604401602060405180830381600087803b1580156139ba57600080fd5b505af11580156139ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139f29190615394565b613a2d5760405162461bcd60e51b815260206004820152600c60248201526b0e4c4c4e9bdd5d189bdd5b9960a21b60448201526064016111bd565b5060006115a1565b600854600160a81b900460ff16613a4b83612ee9565b1115613a695760405162461bcd60e51b81526004016111bd9061548c565b600062093a8080613a7a86426152d4565b613a8491906152a1565b613a8e91906152b5565b905060008511613a9d57600080fd5b428111613afb5760405162461bcd60e51b815260206004820152602660248201527f43616e206f6e6c79206c6f636b20756e74696c2074696d6520696e207468652060448201526566757475726560d01b60648201526084016111bd565b613b0862eff100426152d4565b811115613b575760405162461bcd60e51b815260206004820152601f60248201527f566f74696e67206c6f636b2063616e206265203236207765656b73206d61780060448201526064016111bd565b600760008154613b66906152ec565b90915550600754613b778482614aab565b5060008181526012602090815260409182902082518084019093528054600f0b835260019081015491830191909152613bb591839189918691613f9d565b91506115a19050565b600080839050600062093a80808360400151613bda91906152a1565b613be491906152b5565b905060005b60ff811015613c9857613bff62093a80836152d4565b9150600085831115613c1357859250613c27565b50600082815260146020526040902054600f0b5b6040840151613c36908461537d565b8460200151613c459190615514565b84518590613c549083906155a9565b600f0b90525082861415613c685750613c98565b8084602001818151613c7a91906155f9565b600f0b9052505060408301829052613c91816152ec565b9050613be9565b5060008260000151600f0b1215613cae57600082525b50516001600160801b03169392505050565b600043821115613cd257613cd2615345565b600083815260106020526040812054815b6080811015613d7657818310613cf857613d76565b60006002613d0684866152d4565b613d119060016152d4565b613d1b91906152a1565b6000888152601160205260409020909150869082633b9aca008110613d4257613d42615307565b600302016002015411613d5757809350613d65565b613d6260018261537d565b92505b50613d6f816152ec565b9050613ce3565b50600085815260116020526040812083633b9aca008110613d9957613d99615307565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b602083015260018101549282019290925260029091015460608201526013549091506000613dee878361419c565b600081815260056020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508084841015613ecd576000600581613e528760016152d4565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060808301829052860151919250613eaf919061537d565b925083604001518160400151613ec5919061537d565b915050613ef1565b6060830151613edc904361537d565b9150826040015142613eee919061537d565b90505b60408301518215613f2e578284606001518c613f0d919061537d565b613f1790846152b5565b613f2191906152a1565b613f2b90826152d4565b90505b6040870151613f3d908261537d565b8760200151613f4c9190615514565b87518890613f5b9083906155a9565b600f90810b90915288516000910b129050613f8b57505093516001600160801b03169650610f2495505050505050565b60009950505050505050505050610f24565b6015548290613fac86826152d4565b6015556040805180820190915260008082526020820152825160208085015190830152600f0b8152825187908490613fe59083906155f9565b600f0b9052508515613ff957602083018690525b6000888152601260209081526040909120845181546001600160801b0319166001600160801b039091161781559084015160019091015561403b88828561306d565b33871580159061405d5750600485600481111561405a5761405a615687565b14155b15614101576000546040516323b872dd60e01b81526001600160a01b038381166004830152306024830152604482018b905262010000909204909116906323b872dd90606401602060405180830381600087803b1580156140bd57600080fd5b505af11580156140d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140f59190615394565b61410157614101615345565b8360200151816001600160a01b03167fff04ccafc360e16b67d682d17bd9503c4c6b9a131f6be6325762dc9ffc7de6248b8b8942604051614145949392919061569d565b60405180910390a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c836141798a826152d4565b6040805192835260208301919091520160405180910390a1505050505050505050565b60008082815b608081101561421c578183106141b75761421c565b600060026141c584866152d4565b6141d09060016152d4565b6141da91906152a1565b60008181526005602052604090206002015490915087106141fd5780935061420b565b61420860018261537d565b92505b50614215816152ec565b90506141a2565b5090949350505050565b6000818152600960205260409020546001600160a01b0383811691161461424f5761424f615345565b6000818152600b60205260409020546001600160a01b031615614289576000818152600b6020526040902080546001600160a01b03191690555b5050565b6000818152600960205260409020546001600160a01b038381169116146142b6576142b6615345565b600081815260096020526040902080546001600160a01b03191690556142dc8282614b0a565b6001600160a01b0382166000908152600a6020526040812080546001929061430590849061537d565b90915550505050565b816001600160a01b0316836001600160a01b0316141580156143305750600081115b15611147576001600160a01b038316156144b1576001600160a01b0383166000908152601b602052604081205463ffffffff169081614394576001600160a01b0385166000908152601a6020908152604080832083805290915290206001016143d6565b6001600160a01b0385166000908152601a60205260408120906143b8600185615243565b63ffffffff1663ffffffff1681526020019081526020016000206001015b905060006143e386614bbc565b6001600160a01b0387166000908152601a6020908152604080832063ffffffff8516845290915281209192506001909101905b835481101561447057600084828154811061443357614433615307565b9060005260206000200154905086811461445d578254600181018455600084815260209020018190555b5080614468816152ec565b915050614416565b5061447c8460016156db565b6001600160a01b0388166000908152601b60205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03821615611147576001600160a01b0382166000908152601b602052604081205463ffffffff169081614510576001600160a01b0384166000908152601a602090815260408083208380529091529020600101614552565b6001600160a01b0384166000908152601a6020526040812090614534600185615243565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061455f85614bbc565b6001600160a01b0386166000908152601a6020908152604080832063ffffffff8516845290915290208354919250600190810191610400916145a191906152d4565b11156145bf5760405162461bcd60e51b81526004016111bd90615703565b60005b83548110156146115760008482815481106145df576145df615307565b600091825260208083209091015485546001810187558684529190922001555080614609816152ec565b9150506145c2565b508054600181810183556000838152602090209091018690556146359085906156db565b6001600160a01b0387166000908152601b60205260409020805463ffffffff9290921663ffffffff1990921691909117905550505050505050565b6000818152600960205260409020546001600160a01b03161561469557614695615345565b600081815260096020526040902080546001600160a01b0319166001600160a01b0384161790556146c68282614c35565b6001600160a01b0382166000908152600a602052604081208054600192906143059084906152d4565b806001600160a01b0316826001600160a01b031614611147576001600160a01b038216156148a2576001600160a01b0382166000908152601b602052604081205463ffffffff169081614767576001600160a01b0384166000908152601a6020908152604080832083805290915290206001016147a9565b6001600160a01b0384166000908152601a602052604081209061478b600185615243565b63ffffffff1663ffffffff1681526020019081526020016000206001015b905060006147b685614bbc565b6001600160a01b0386166000908152601a6020908152604080832063ffffffff8516845290915281209192506001909101905b835481101561486157600084828154811061480657614806615307565b600091825260208083209091015480835260099091526040909120549091506001600160a01b03908116908a161461484e578254600181018455600084815260209020018190555b5080614859816152ec565b9150506147e9565b5061486d8460016156db565b6001600160a01b0387166000908152601b60205260409020805463ffffffff191663ffffffff92909216919091179055505050505b6001600160a01b03811615611147576001600160a01b0381166000908152601b602052604081205463ffffffff169081614901576001600160a01b0383166000908152601a602090815260408083208380529091529020600101614943565b6001600160a01b0383166000908152601a6020526040812090614925600185615243565b63ffffffff1663ffffffff1681526020019081526020016000206001015b9050600061495084614bbc565b6001600160a01b038086166000908152601a6020908152604080832063ffffffff861684528252808320938b168352600a9091529020548454929350600190910191610400906149a19083906152d4565b11156149bf5760405162461bcd60e51b81526004016111bd90615703565b60005b8454811015614a115760008582815481106149df576149df615307565b600091825260208083209091015486546001810188558784529190922001555080614a09816152ec565b9150506149c2565b5060005b81811015614a63576001600160a01b0389166000908152600e602090815260408083208484528252822054855460018101875586845291909220015580614a5b816152ec565b915050614a15565b50614a6f8560016156db565b6001600160a01b0387166000908152601b60205260409020805463ffffffff9290921663ffffffff199092169190911790555050505050505050565b60006001600160a01b038316614ac357614ac3615345565b614ad16000612fbb85611895565b614adb8383614670565b60405182906001600160a01b03851690600090600080516020615747833981519152908290a450600192915050565b60006001614b1784612ee9565b614b21919061537d565b6000838152600f602052604090205490915080821415614b71576001600160a01b0384166000908152600e602090815260408083208584528252808320839055858352600f9091528120556124f5565b6001600160a01b03939093166000908152600e6020908152604080832093835292815282822080548684528484208190558352600f9091528282209490945592839055908252812055565b6001600160a01b0381166000908152601b6020526040812054429063ffffffff168015801590614c2557506001600160a01b0384166000908152601a602052604081208391614c0c600185615243565b63ffffffff168152602081019190915260400160002054145b156115a157611a2c600182615243565b6000614c4083612ee9565b6001600160a01b039093166000908152600e602090815260408083208684528252808320859055938252600f9052919091209190915550565b6001600160e01b03198116811461192d57600080fd5b600060208284031215614ca157600080fd5b81356115a181614c79565b60005b83811015614cc7578181015183820152602001614caf565b838111156124f55750506000910152565b60008151808452614cf0816020860160208601614cac565b601f01601f19169290920160200192915050565b6020815260006115a16020830184614cd8565b80356001600160a01b0381168114614d2e57600080fd5b919050565b60008060408385031215614d4657600080fd5b614d4f83614d17565b946020939093013593505050565b600060208284031215614d6f57600080fd5b5035919050565b600060208284031215614d8857600080fd5b6115a182614d17565b60008060408385031215614da457600080fd5b50508035926020909101359150565b600080600060608486031215614dc857600080fd5b614dd184614d17565b9250614ddf60208501614d17565b9150604084013590509250925092565b60008060408385031215614e0257600080fd5b614e0b83614d17565b9150614e1960208401614d17565b90509250929050565b803560ff81168114614d2e57600080fd5b600060208284031215614e4557600080fd5b6115a182614e22565b6020808252825182820181905260009190848201906040850190845b81811015614e8657835183529284019291840191600101614e6a565b50909695505050505050565b801515811461192d57600080fd5b60008060408385031215614eb357600080fd5b614ebc83614d17565b91506020830135614ecc81614e92565b809150509250929050565b600060208284031215614ee957600080fd5b81356115a181614e92565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614f3357614f33614ef4565b604052919050565b600067ffffffffffffffff821115614f5557614f55614ef4565b50601f01601f191660200190565b60008060008060808587031215614f7957600080fd5b614f8285614d17565b9350614f9060208601614d17565b925060408501359150606085013567ffffffffffffffff811115614fb357600080fd5b8501601f81018713614fc457600080fd5b8035614fd7614fd282614f3b565b614f0a565b818152886020838501011115614fec57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060008060008060c0878903121561502757600080fd5b61503087614d17565b9550602087013594506040870135935061504c60608801614e22565b92506080870135915060a087013590509295509295509295565b6000602080838503121561507957600080fd5b823567ffffffffffffffff8082111561509157600080fd5b818501915085601f8301126150a557600080fd5b8135818111156150b7576150b7614ef4565b8060051b91506150c8848301614f0a565b81815291830184019184810190888411156150e257600080fd5b938501935b83851015615100578435825293850193908501906150e7565b98975050505050505050565b60008060006060848603121561512157600080fd5b833592506020840135915061513860408501614d17565b90509250925092565b6000806040838503121561515457600080fd5b61515d83614d17565b9150602083013563ffffffff81168114614ecc57600080fd5b60006020828403121561518857600080fd5b815167ffffffffffffffff81111561519f57600080fd5b8201601f810184136151b057600080fd5b80516151be614fd282614f3b565b8181528560208385010111156151d357600080fd5b6151e4826020830160208601614cac565b95945050505050565b600082516151ff818460208701614cac565b6e0102b37ba34b7339022b9b1b937bb9608d1b920191825250630f09f94960e41b600f820152601301919050565b634e487b7160e01b600052601160045260246000fd5b600063ffffffff838116908316818110156152605761526061522d565b039392505050565b634e487b7160e01b600052601260045260246000fd5b600063ffffffff8084168061529557615295615268565b92169190910492915050565b6000826152b0576152b0615268565b500490565b60008160001904831182151516156152cf576152cf61522d565b500290565b600082198211156152e7576152e761522d565b500190565b60006000198214156153005761530061522d565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6020808252600e908201526d4e6f2072652d656e7472616e637960901b604082015260600190565b634e487b7160e01b600052600160045260246000fd5b602080825260089082015267185d1d1858da195960c21b604082015260600190565b60008282101561538f5761538f61522d565b500390565b6000602082840312156153a657600080fd5b81516115a181614e92565b602080825260039082015262216d7360e81b604082015260600190565b61766560f01b8152600082516153eb816002850160208701614cac565b9190910160020192915050565b60208082526024908201527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686040820152636472617760e01b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611ee690830184614cd8565b60006020828403121561548157600080fd5b81516115a181614c79565b6020808252602a908201527f45786365656473204d6178204e465420486f6c64696e67204c696d69742070656040820152697220616464726573732160b01b606082015260800190565b600081600f0b83600f0b806154ed576154ed615268565b60016001607f1b031982146000198214161561550b5761550b61522d565b90059392505050565b600081600f0b83600f0b60016001607f1b036000821360008413838304851182821616156155445761554461522d565b60016001607f1b031960008512828116878305871216156155675761556761522d565b600087129250858205871284841616156155835761558361522d565b858505871281841616156155995761559961522d565b5050509290910295945050505050565b600081600f0b83600f0b600081128160016001607f1b0319018312811516156155d4576155d461522d565b8160016001607f1b030183138116156155ef576155ef61522d565b5090039392505050565b600081600f0b83600f0b600082128260016001607f1b03038213811516156156235761562361522d565b8260016001607f1b031903821281161561563f5761563f61522d565b50019392505050565b60008083128015600160ff1b8501841216156156665761566661522d565b6001600160ff1b03840183138116156156815761568161522d565b50500390565b634e487b7160e01b600052602160045260246000fd5b8481526020810184905260808101600584106156c957634e487b7160e01b600052602160045260246000fd5b60408201939093526060015292915050565b600063ffffffff8083168185168083038211156156fa576156fa61522d565b01949350505050565b60208082526023908201527f64737452657020776f756c64206861766520746f6f206d616e7920746f6b656e60408201526249647360e81b60608201526080019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220d2ffb784f3a3c51df6bf36e0bcac00d5ba3249877112db76334fc59a2a2f92bd64736f6c63430008090033
Deployed Bytecode Sourcemap
28390:60376:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45616:136;;;;;;:::i;:::-;-1:-1:-1;;;;;;45711:33:0;45687:4;45711:33;;;:19;:33;;;;;;;;;45616:136;;;;565:14:1;;558:22;540:41;;528:2;513:18;45616:136:0;;;;;;;;50816:18;;;;;;;;;738:25:1;;;726:2;711:18;50816::0;592:177:1;32636:155:0;;;:::i;:::-;;;;;;;:::i;78530:1064::-;;;;;;:::i;:::-;;:::i;:::-;;;2136:10:1;2124:23;;;2106:42;;2094:2;2079:18;78530:1064:0;1962:192:1;35916:117:0;;;;;;:::i;:::-;35975:7;36002:23;;;:13;:23;;;;;;-1:-1:-1;;;;;36002:23:0;;35916:117;;;;-1:-1:-1;;;;;2508:32:1;;;2490:51;;2478:2;2463:18;35916:117:0;2344:203:1;33129:110:0;;;;;;:::i;:::-;;:::i;:::-;;37137:658;;;;;;:::i;:::-;;:::i;74612:40::-;;;;;;:::i;:::-;;;;;;;;;;;;;;50563: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;50563:60:0;2996:419:1;65191:370:0;;;:::i;73271:109::-;;;:::i;51810:150::-;;;;;;:::i;:::-;;:::i;76472:122::-;;76514:80;76472:122;;42002:174;;;;;;:::i;:::-;;:::i;60103:91::-;60174:12;60103:91;;65673:977;;;;;;:::i;:::-;;:::i;33247:120::-;;;;;;:::i;:::-;;:::i;46248:159::-;;;;;;:::i;:::-;-1:-1:-1;;;;;46358:28:0;;;;46334:4;46358:28;;;:20;:28;;;;;;;;:41;;;;;;;;;46248:159;32594:35;;32627:2;32594:35;;;;;4107:4:1;4095:17;;;4077:36;;4065:2;4050:18;32594:35:0;3935:184:1;79602:582:0;;;;;;:::i;:::-;;:::i;88375:114::-;;;;;;:::i;:::-;;:::i;42907:173::-;;;;;;:::i;:::-;;:::i;39856:153::-;;;;;;:::i;:::-;;:::i;51409:194::-;;;;;;:::i;:::-;;:::i;:::-;;;4297:2:1;4286:22;;;;4268:41;;4256:2;4241:18;51409:194:0;4124:191:1;30000:20:0;;;;;-1:-1:-1;;;;;30000:20:0;;;31289:727;;;;;;:::i;:::-;;:::i;74702:115::-;;;;;;:::i;:::-;;:::i;32547:40::-;;;;;;;;;;;;;;;-1:-1:-1;;;32547:40:0;;;;;30077:23;;;;;-1:-1:-1;;;;;30077:23:0;;;77635:187;;;;;;:::i;:::-;;:::i;85950:230::-;;;;;;:::i;:::-;;:::i;76919:41::-;;76956:4;76919:41;;88497:122;;;;;;:::i;:::-;;:::i;34462:107::-;;;;;;:::i;:::-;34515:7;34542:19;;;:9;:19;;;;;;-1:-1:-1;;;;;34542:19:0;;34462:107;62701:166;;;;;;:::i;:::-;;:::i;35740:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;77249:48;;;;;;:::i;:::-;;;;;;;;;;;;;;;;35169:106;;;;;;:::i;:::-;;:::i;73554:198::-;;;;;;:::i;:::-;;:::i;50734:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;73918:90;73992:7;;73918:90;;73802:108;;;:::i;77378:38::-;;;;;;:::i;:::-;;;;;;;;;;;;;;74126:287;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;30027:19::-;;;;;-1:-1:-1;;;;;30027:19:0;;;71001:140;;;;;;:::i;:::-;;:::i;80192:127::-;;;;;;:::i;:::-;;:::i;74659:34::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;50710:17;;;;;;88248:119;;;;;;:::i;:::-;;:::i;32797:132::-;;;:::i;87633:502::-;;;;;;:::i;:::-;;:::i;71337:880::-;;;;;;:::i;:::-;;:::i;75285:194::-;;;;;;:::i;:::-;;:::i;78023:499::-;;;;;;:::i;:::-;;:::i;30053:17::-;;;;;-1:-1:-1;;;;;30053:17:0;;;63491:507;;;;;;:::i;:::-;;:::i;38307:301::-;;;;;;:::i;:::-;;:::i;30838:25::-;;;;;-1:-1:-1;;;30838:25:0;;;;;;64134:728;;;;;;:::i;:::-;;:::i;88627:134::-;;;;;;:::i;:::-;;:::i;50659:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6460:2:1;6449:22;;;;6431:41;;6503:2;6488:18;;6481:34;;;;6404:18;50659:44:0;6259:262:1;44289:1020:0;;;;;;:::i;:::-;;:::i;30806:23::-;;;;;;;;-1:-1:-1;;;;;30806:23:0;;;74953:122;;;;;;:::i;:::-;;:::i;60252:106::-;;;:::i;86188:1265::-;;;;;;:::i;:::-;;:::i;64870:313::-;;;;;;:::i;:::-;;:::i;33476:431::-;;;;;;:::i;:::-;;:::i;74016:102::-;;;:::i;75487:722::-;;;;;;:::i;:::-;;:::i;30109:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;30109:43:0;;;;;;;;;63135:176;;;;;;:::i;:::-;;:::i;88143:97::-;;;:::i;68863:130::-;;;;;;:::i;:::-;;:::i;50511:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;76688:117;;76734:71;76688:117;;68656:199;;;;;;:::i;:::-;;:::i;36242:153::-;;;;;;:::i;:::-;-1:-1:-1;;;;;36351:24:0;;;36326:4;36351:24;;;:16;:24;;;;;;;;36350:37;;;;;;;;;;;;;;;36242:153;60683:455;;;;;;:::i;:::-;;:::i;76989:30::-;;;;;;;;;77112:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;52109:111;;;;;;:::i;:::-;52168:4;52192:16;;;:6;:16;;;;;:20;;;;52109:111;75083:194;;;;;;:::i;:::-;;:::i;29973:20::-;;;;;;;;-1:-1:-1;;;;;29973:20:0;;;74825:120;;;;;;:::i;:::-;;:::i;32636:155::-;32672:13;32736:5;;;;;;;;;-1:-1:-1;;;;;32736:5:0;-1:-1:-1;;;;;32729:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32729:20:0;;;;;;;;;;;;:::i;:::-;32712:70;;;;;;;;:::i;:::-;;;;;;;;;;;;;32698:85;;32636:155;:::o;78530:1064::-;-1:-1:-1;;;;;78652:23:0;;78611:6;78652:23;;;:14;:23;;;;;;;;78690:17;78686:58;;78731:1;78724:8;;;;;78686:58;-1:-1:-1;;;;;78802:20:0;;;;;;:11;:20;;;;;78854:9;;78823:16;78838:1;78823:12;:16;:::i;:::-;78802:38;;;;;;;;;;;;;-1:-1:-1;78802:38:0;:48;:61;78798:119;;78888:16;78903:1;78888:12;:16;:::i;:::-;78880:25;;;;;78798:119;-1:-1:-1;;;;;78978:20:0;;;;;;:11;:20;;;;;;;;:23;;;;;;;;:33;:45;-1:-1:-1;78974:86:0;;;79047:1;79040:8;;;;;78974:86;79072:12;;79114:16;79129:1;79114:12;:16;:::i;:::-;79099:31;;79141:423;79156:5;79148:13;;:5;:13;;;79141:423;;;79178:13;79220:1;79203:13;79211:5;79203;:13;:::i;:::-;79202:19;;;;:::i;:::-;79194:27;;:5;:27;:::i;:::-;-1:-1:-1;;;;;79287:20:0;;79263:21;79287:20;;;:11;:20;;;;;;;;:28;;;;;;;;;;79334:12;;79178:43;;-1:-1:-1;79287:28:0;79334:25;;79330:223;;;-1:-1:-1;79387:6:0;-1:-1:-1;79380:13:0;;-1:-1:-1;;;79380:13:0;79330:223;79419:12;;:24;-1:-1:-1;79415:138:0;;;79472:6;79464:14;;79415:138;;;79527:10;79536:1;79527:6;:10;:::i;:::-;79519:18;;79415:138;79163:401;;79141:423;;;-1:-1:-1;79581:5:0;-1:-1:-1;;78530:1064:0;;;;;:::o;33129:110::-;33203:4;;-1:-1:-1;;;;;33203:4:0;33189:10;:18;33181:27;;;;;;33219:4;:12;;-1:-1:-1;;;;;;33219:12:0;-1:-1:-1;;;;;33219:12:0;;;;;;;;;;33129:110::o;37137:658::-;37206:13;37222:19;;;:9;:19;;;;;;-1:-1:-1;;;;;37222:19:0;37312;37304:28;;;;;;37419:5;-1:-1:-1;;;;;37406:18:0;:9;-1:-1:-1;;;;;37406:18:0;;;37398:27;;;;;;37467:18;37489:19;;;:9;:19;;;;;;;;;-1:-1:-1;;;;;37565:23:0;;;;;:16;:23;;;;;37512:10;37564:37;;;;;;;;;;37489:19;;:33;;37564:37;;37489:33;;37620:39;;;37637:22;37620:39;37612:48;;;;;;37700:23;;;;:13;:23;;;;;;:35;;-1:-1:-1;;;;;;37700:35:0;-1:-1:-1;;;;;37700:35:0;;;;;;;;;37751:36;;37700:23;;37751:36;;;;;;;37195:600;;;37137:658;;:::o;50563:60::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;50563:60:0;;;;;;;-1:-1:-1;50563:60:0;:::o;65191:370::-;65227:9;65239:20;65248:10;65239:8;:20::i;:::-;65227:32;-1:-1:-1;65267:9:0;50920:14;50873:7;65279:22;50873:7;65279:15;:22;:::i;:::-;:29;;;;:::i;:::-;:39;;;;:::i;:::-;65267:51;;65330:6;65326:228;65340:4;65338:1;:6;65326:228;;;65393:10;65360:9;65372:32;;;:20;:32;;;;;;;;:35;;;;;;;;;65428:12;;;:6;:12;;;;;:16;;;65372:35;;65360:9;50873:7;;65428:23;;50873:7;;65428:23;:::i;:::-;:30;;;;:::i;:::-;65416:42;;65478:4;65471;:11;65468:78;;;65497:38;65519:4;50920:14;65497:20;:38::i;:::-;65351:203;;65346:3;;;;;:::i;:::-;;;;65326:228;;;;65222:339;;65191:370::o;73271:109::-;73317:4;73341:31;73356:15;73341:14;:31::i;:::-;73334:38;;73271:109;:::o;51810:150::-;51891:4;51915:28;;;:18;:28;;;;;51944:4;51915:34;;;;;;;:::i;:::-;;;;:37;;;51908:44;;51810:150;;;;:::o;42002:174::-;42121:47;42135:5;42142:3;42147:8;42157:10;42121:13;:47::i;65673:977::-;32253:7;;;;32252:8;32244:35;;;;-1:-1:-1;;;32244:35:0;;;;;;;:::i;:::-;;;;;;;;;32290:7;:14;;-1:-1:-1;;32290:14:0;32300:4;32290:14;;;65746:40:::1;65765:10;65777:8:::0;65746:18:::1;:40::i;:::-;65739:48;;;;:::i;:::-;65806:21;::::0;;;:11:::1;:21;::::0;;;;;:26;:46;::::1;;;-1:-1:-1::0;65837:15:0::1;::::0;;;:5:::1;:15;::::0;;;;;::::1;;65836:16;65806:46;65798:67;;;;-1:-1:-1::0;;;65798:67:0::1;;;;;;;:::i;:::-;65878:29;65910:16:::0;;;:6:::1;:16;::::0;;;;;;;;65878:48;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;65945:15:::1;:31;;65937:66;;;::::0;-1:-1:-1;;;65937:66:0;;13846:2:1;65937: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;;65937:66:0::1;13644:346:1::0;65937:66:0::1;66039:15:::0;;66088:18:::1;::::0;;;;::::1;::::0;;-1:-1:-1;66088:18:0;;;::::1;::::0;;::::1;::::0;;;66069:16;;;:6:::1;:16:::0;;;;;;:37;;;;-1:-1:-1;;;;;;66069:37:0::1;-1:-1:-1::0;;;;;66069:37:0;;;::::1;::::0;;;;-1:-1:-1;66069:37:0;;::::1;::::0;66138:6:::1;::::0;66032:23:::1;::::0;;;::::1;::::0;66164:21:::1;66032:23:::0;66138:6;66164:21:::1;:::i;:::-;66155:6;:30:::0;66376:18:::1;::::0;;;;::::1;::::0;;;-1:-1:-1;66376:18:0;;;::::1;::::0;::::1;::::0;66344:51:::1;::::0;66356:8;;66366;;66344:11:::1;:51::i;:::-;66422:5;::::0;66415:41:::1;::::0;-1:-1:-1;;;66415:41:0;;66438:10:::1;66415:41;::::0;::::1;14299:51:1::0;14366:18;;;14359:34;;;66422:5:0;;;::::1;-1:-1:-1::0;;;;;66422:5:0::1;::::0;66415:22:::1;::::0;14272:18:1;;66415:41:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66408:49;;;;:::i;:::-;66495:15;66501:8;66495:5;:15::i;:::-;66528:54;::::0;;14856:25:1;;;14912:2;14897:18;;14890:34;;;66566:15:0::1;14940:18:1::0;;;14933:34;66528:54:0;;66537:10:::1;::::0;66528:54:::1;::::0;;;;;14844:2:1;66528:54:0;;::::1;66598:44;66605:13:::0;66620:21:::1;66636:5:::0;66605:13;66620:21:::1;:::i;:::-;66598:44;::::0;;15152:25:1;;;15208:2;15193:18;;15186:34;;;;15125:18;66598:44:0::1;;;;;;;-1:-1:-1::0;;32327:7:0;:15;;-1:-1:-1;;32327:15:0;;;-1:-1:-1;;65673:977:0:o;33247:120::-;33326:4;;-1:-1:-1;;;;;33326:4:0;33312:10;:18;33304:27;;;;;;33342:8;:17;;-1:-1:-1;;;;;;33342:17:0;-1:-1:-1;;;;;33342:17:0;;;;;;;;;;33247:120::o;79602:582::-;79705:4;79727:18;79748:37;79766:7;79775:9;79748:17;:37::i;:::-;-1:-1:-1;;;;;79845:20:0;;79818:24;79845:20;;;:11;:20;;;;;;;;:33;;;;;;;;;;79727:58;;-1:-1:-1;79845:42:0;;;;;79818:24;79923:231;79944:16;;79940:20;;79923:231;;;79982:8;79993:9;80003:1;79993:12;;;;;;;;:::i;:::-;;;;;;;;;79982:23;;80113:29;80127:3;80132:9;80113:13;:29::i;:::-;80105:37;;:5;:37;:::i;:::-;80097:45;;79967:187;79962:3;;;;;:::i;:::-;;;;79923:231;;;-1:-1:-1;80171:5:0;79602:582;-1:-1:-1;;;;;79602:582:0:o;88375:114::-;88450:2;;-1:-1:-1;;;;;88450:2:0;88436:10;:16;88428:32;;;;-1:-1:-1;;;88428:32:0;;;;;;;:::i;:::-;88471:5;:10;;-1:-1:-1;;;;;;88471:10:0;-1:-1:-1;;;;;88471:10:0;;;;;;;;;;88375:114::o;42907:173::-;43030:42;43047:5;43054:3;43059:8;43030:42;;;;;;;;;;;;:16;:42::i;39856:153::-;39939:4;39963:38;39982:8;39992;39963:18;:38::i;:::-;39956:45;39856:153;-1:-1:-1;;;39856:153:0:o;51409:194::-;51476:6;51509:26;;;:16;:26;;;;;;;;;51553:18;:28;;;;;51509:26;51553:36;;;;;;;:::i;:::-;;;;:42;-1:-1:-1;;;51553:42:0;;;;;51409:194;-1:-1:-1;;;51409:194:0:o;31289:727::-;25342:19;25365:13;;;;;;25364:14;;25412:34;;;;-1:-1:-1;25430:12:0;;25445:1;25430:12;;;;:16;25412:34;25411:108;;;-1:-1:-1;25491:4:0;16104:19;:23;;;25452:66;;-1:-1:-1;25501:12:0;;;;;:17;25452:66;25389:204;;;;-1:-1:-1;;;25389:204:0;;15764:2:1;25389: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;;25389:204:0;15562:410:1;25389:204:0;25604:12;:16;;-1:-1:-1;;25604:16:0;25619:1;25604:16;;;25631:67;;;;25666:13;:20;;-1:-1:-1;;25666:20:0;;;;;25631:67;31403:5:::1;:18:::0;;-1:-1:-1;;;;;;31403:18:0::1;::::0;-1:-1:-1;;;;;31403:18:0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;31432:18:0;;31440:10:::1;-1:-1:-1::0;;;;;;31432:18:0;;::::1;::::0;::::1;::::0;;31403:5:::1;31461:17:::0;;;::::1;::::0;::::1;::::0;;31489:2:::1;:15:::0;;;::::1;::::0;;::::1;::::0;;31515:8:::1;:20:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;31546:12:::1;:17:::0;;-1:-1:-1;;;;31546:17:0::1;-1:-1:-1::0;;;31546:17:0::1;::::0;;31599:12:::1;31576:20:::0;:35;31644:15:::1;31622:19:::0;:37;31672:19:::1;31576:16;31672:40:::0;;:47;;-1:-1:-1;;31672:47:0;;::::1;::::0;::::1;::::0;;;31730:40;:47;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;31788:49:0;;;:56;;;;::::1;::::0;;::::1;::::0;;31919:7:::1;::::0;31576:16;31883:44;31919:7;;31912:4:::1;::::0;-1:-1:-1;;;;;;;;;;;31883:44:0;31403:5;;31883:44:::1;32000:7;::::0;31964:44:::1;::::0;31996:1:::1;::::0;31981:4:::1;::::0;-1:-1:-1;;;;;;;;;;;31964:44:0;31996:1;;31964:44:::1;25724:14:::0;25720:102;;;25771:5;25755:21;;-1:-1:-1;;25755:21:0;;;25796:14;;-1:-1:-1;4077:36:1;;25796:14:0;;4065:2:1;4050:18;25796:14:0;;;;;;;25331:498;31289:727;;:::o;74702:115::-;74778:5;;-1:-1:-1;;;;;74778:5:0;74764:10;:19;74756:28;;;;;77635:187;-1:-1:-1;;;;;77732:21:0;;;77694:7;77732:21;;;:10;:21;;;;;;77694:7;;77732:21;77771;;:43;;77807:7;77771:43;;;-1:-1:-1;77795:9:0;;77764:50;-1:-1:-1;77635:187:0:o;85950:230::-;86013:18;;;;86005:55;;;;-1:-1:-1;;;86005:55:0;;16378:2:1;86005:55:0;;;16360:21:1;16417:2;16397:18;;;16390:30;-1:-1:-1;;;16436:18:1;;;16429:54;16500:18;;86005:55:0;16176:348:1;86005:55:0;-1:-1:-1;;;;;86075:23:0;;86071:51;;-1:-1:-1;86112:10:0;86071:51;86140:32;86150:10;86162:9;86140;:32::i;:::-;85950:230;:::o;88497:122::-;88573:2;;-1:-1:-1;;;;;88573:2:0;88559:10;:16;88551:32;;;;-1:-1:-1;;;88551:32:0;;;;;;;:::i;:::-;88594:12;:17;;;;;;-1:-1:-1;;;88594:17:0;-1:-1:-1;;;;88594:17:0;;;;;;;;;88497:122::o;62701:166::-;32253:7;;62787:4;;32253:7;;32252:8;32244:35;;;;-1:-1:-1;;;32244:35:0;;;;;;;:::i;:::-;32290:7;:14;;-1:-1:-1;;32290:14:0;32300:4;32290:14;;;62811:48:::1;62824:6:::0;62832:14;62848:10:::1;62811:12;:48::i;:::-;32327:7:::0;:15;;-1:-1:-1;;32327:15:0;;;62804:55;62701:166;-1:-1:-1;;;62701:166:0:o;35169:106::-;35227:4;35251:16;35260:6;35251:8;:16::i;73554:198::-;73638:5;;73607:4;73680:21;;;:13;:21;;;;;;;;73654:47;;;;;;;;;;;;;;;-1:-1:-1;;;73654:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73607:4;;73638:5;73719:25;73654:47;73742:1;73719:10;:25::i;:::-;73712:32;73554:198;-1:-1:-1;;;;73554:198:0:o;73802:108::-;73846:4;73880:20;73897:1;73880:8;:20::i;:::-;73870:7;;:30;;;;:::i;74126:287::-;74184:13;74210:10;74223:14;74232:4;74223:8;:14::i;:::-;74210:27;;74248:17;74279:5;74268:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74268:17:0;;74248:37;;74300:6;74296:89;74309:5;74307:1;:7;74296:89;;;-1:-1:-1;;;;;74344:26:0;;;;;;:20;:26;;;;;;;;:29;;;;;;;;;74335:6;;:3;;74371:1;;74335:6;;;;;;:::i;:::-;;;;;;;;;;:38;74315:3;;;;:::i;:::-;;;;74296:89;;;-1:-1:-1;74402:3:0;74126:287;-1:-1:-1;;;74126:287:0:o;71001:140::-;71076:4;71100:33;71116:8;71126:6;71100:15;:33::i;80192:127::-;80262:4;80286:25;80301:9;80286:14;:25::i;88248:119::-;88324:2;;-1:-1:-1;;;;;88324:2:0;88310:10;:16;88302:32;;;;-1:-1:-1;;;88302:32:0;;;;;;;:::i;:::-;88345:8;:14;;-1:-1:-1;;;;;88345:14:0;;;;;-1:-1:-1;;;;;;88345:14:0;;;;;;;;;88248:119::o;32797:132::-;32835:13;32904:5;;;;;;;;;-1:-1:-1;;;;;32904:5:0;-1:-1:-1;;;;;32897:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32897:22:0;;;;;;;;;;;;:::i;:::-;32875:45;;;;;;;;:::i;87633:502::-;32253:7;;;;32252:8;32244:35;;;;-1:-1:-1;;;32244:35:0;;;;;;;:::i;:::-;32290:7;:14;;-1:-1:-1;;32290:14:0;32300:4;32290:14;;;87745:4:::1;::::0;87731:10:::1;-1:-1:-1::0;;;;;87745:4:0;;::::1;87731:18;87723:39;;;::::0;-1:-1:-1;;;87723:39:0;;17155:2:1;87723: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;;87723:39:0::1;16953:331:1::0;87723:39:0::1;87775:29;87807:16:::0;;;:6:::1;:16;::::0;;;;;;;;87775:48;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;87843:10;87836:18:::1;;;;:::i;:::-;87919:1;87901:8;:15;;;:19;;;87893:54;;;::::0;-1:-1:-1;;;87893:54:0;;17491:2:1;87893: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;;87893:54:0::1;17289:346:1::0;87893:54:0::1;87981:15;87966:8;:12;;;:30;87958:79;;;;-1:-1:-1::0;;;87958:79:0::1;;;;;;;:::i;:::-;88050:77;88063:8;88073:6;88081:1;88084:8;88094:32;88050:12;:77::i;:::-;-1:-1:-1::0;;32327:7:0;:15;;-1:-1:-1;;32327:15:0;;;-1:-1:-1;87633:502:0:o;71337:880::-;71396:4;71430:12;71420:6;:22;;71413:30;;;;:::i;:::-;71468:5;;71454:11;71504:33;71522:6;71468:5;71504:17;:33::i;:::-;71550:18;71571:27;;;:13;:27;;;;;;;;71550:48;;;;;;;;;;;;;;;-1:-1:-1;;;71550:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71484:53;;-1:-1:-1;71635:21:0;;;71631:465;;;71673:23;71699:13;71673:23;71713:16;:12;71728:1;71713:16;:::i;:::-;71699:31;;;;;;;;;;;;;;-1:-1:-1;71699:31:0;71673:57;;;;;;;;;;;;;;;-1:-1:-1;;;71673:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71749:9;;;71673:57;;-1:-1:-1;71749:27:0;71745:155;;71874:5;:9;;;71857:10;:14;;;:26;;;;:::i;:::-;71843:5;:8;;;71827:10;:13;;;:24;;;;:::i;:::-;71813:9;;;;71804:18;;:6;:18;:::i;:::-;71803:49;;;;:::i;:::-;71802:82;;;;:::i;:::-;71797:87;;71745:155;71658:253;71631:465;;;71949:12;71936:5;:9;;;:25;71932:153;;72059:9;;;;72044:24;;:12;:24;:::i;:::-;72030:8;;;;72012:26;;:15;:26;:::i;:::-;71998:9;;;;71989:18;;:6;:18;:::i;:::-;71988:51;;;;:::i;:::-;71987:82;;;;:::i;:::-;71982:87;;71932:153;72177:32;72188:5;72206:2;72195:5;:8;;;:13;;;;:::i;:::-;72177:10;:32::i;:::-;72170:39;71337:880;-1:-1:-1;;;;;;71337:880:0:o;75285:194::-;75358:8;;;;;-1:-1:-1;;;;;75358:8:0;75344:10;:22;;:45;;-1:-1:-1;75384:5:0;;-1:-1:-1;;;;;75384:5:0;75370:10;:19;75344:45;75336:75;;;;-1:-1:-1;;;75336:75:0;;18247:2:1;75336:75:0;;;18229:21:1;18286:2;18266:18;;;18259:30;-1:-1:-1;;;18305:18:1;;;18298:47;18362:18;;75336:75:0;18045:341:1;75336:75:0;75446:21;;;;:11;:21;;;;;;:25;;75470:1;;75446:25;:::i;:::-;75422:21;;;;:11;:21;;;;;;:49;75285:194::o;78023:499::-;-1:-1:-1;;;;;78120:23:0;;78081:4;78120:23;;;:14;:23;;;;;;;;78158:17;78154:58;;-1:-1:-1;78199:1:0;;78023:499;-1:-1:-1;;78023:499:0:o;78154:58::-;-1:-1:-1;;;;;78249:20:0;;78222:24;78249:20;;;:11;:20;;;;;78222:24;78270:16;78285:1;78270:12;:16;:::i;:::-;78249:38;;;;;;;;;;;;;;;:47;;78222:74;;78307:10;78337:6;78332:160;78353:16;;78349:20;;78332:160;;;78391:8;78402:9;78412:1;78402:12;;;;;;;;:::i;:::-;;;;;;;;;78391:23;;78445:35;78459:3;78464:15;78445:13;:35::i;:::-;78437:43;;:5;:43;:::i;:::-;78429:51;;78376:116;78371:3;;;;;:::i;:::-;;;;78332:160;;;-1:-1:-1;78509:5:0;78023:499;-1:-1:-1;;;;78023:499:0:o;63491:507::-;32253:7;;;;32252:8;32244:35;;;;-1:-1:-1;;;32244:35:0;;;;;;;:::i;:::-;32290:7;:14;;-1:-1:-1;;32290:14:0;32300:4;32290:14;;;63584:40:::1;63603:10;63615:8:::0;63584:18:::1;:40::i;:::-;63577:48;;;;:::i;38307:301::-:0;-1:-1:-1;;;;;38450:23:0;;38463:10;38450:23;;38443:31;;;;:::i;:::-;38502:10;38485:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;38485:39:0;;;;;;;;;;;;:51;;-1:-1:-1;;38485:51:0;;;;;;;;;;38552:48;;540:41:1;;;38485:39:0;;38502:10;38552:48;;513:18:1;38552:48:0;;;;;;;38307:301;;:::o;64134:728::-;32253:7;;;;32252:8;32244:35;;;;-1:-1:-1;;;32244:35:0;;;;;;;:::i;:::-;32290:7;:14;;-1:-1:-1;;32290:14:0;32300:4;32290:14;;;64238:40:::1;64257:10;64269:8:::0;64238:18:::1;:40::i;:::-;64231:48;;;;:::i;:::-;64292:29;64324:16:::0;;;:6:::1;:16;::::0;;;;;;;64292:48;;;;::::1;::::0;;;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;;;50873:7:::1;::::0;64371:32:::1;64389:14:::0;64371:15:::1;:32;:::i;:::-;64370:41;;;;:::i;:::-;:48;;;;:::i;:::-;64351:67;;64491:15;64476:8;:12;;;:30;64468:55;;;::::0;-1:-1:-1;;;64468:55:0;;18593:2:1;64468: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;;64468:55:0::1;18391:336:1::0;64468:55:0::1;64560:1;64542:8;:15;;;:19;;;64534:49;;;::::0;-1:-1:-1;;;64534:49:0;;18934:2:1;64534: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;;64534:49:0::1;18732:341:1::0;64534:49:0::1;64616:8;:12;;;64602:11;:26;64594:70;;;::::0;-1:-1:-1;;;64594:70:0;;19280:2:1;64594:70:0::1;::::0;::::1;19262:21:1::0;19319:2;19299:18;;;19292:30;19358:33;19338:18;;;19331:61;19409:18;;64594:70:0::1;19078:355:1::0;64594:70:0::1;64698:25;50920:14;64698:15;:25;:::i;:::-;64683:11;:40;;64675:84;;;::::0;-1:-1:-1;;;64675:84:0;;19640:2:1;64675:84:0::1;::::0;::::1;19622:21:1::0;19679:2;19659:18;;;19652:30;19718:33;19698:18;;;19691:61;19769:18;;64675:84:0::1;19438:355:1::0;64675:84:0::1;64772:82;64785:8;64795:1;64798:11;64811:8;64821:32;64772:12;:82::i;:::-;-1:-1:-1::0;;32327:7:0;:15;;-1:-1:-1;;32327:15:0;;;-1:-1:-1;;64134:728:0:o;88627:134::-;88709:2;;-1:-1:-1;;;;;88709:2:0;88695:10;:16;88687:32;;;;-1:-1:-1;;;88687:32:0;;;;;;;:::i;:::-;88730:18;:23;;-1:-1:-1;;88730:23:0;;;;;;;;;;88627:134::o;44289:1020::-;44439:47;44453:5;44460:3;44465:8;44475:10;44439:13;:47::i;:::-;43407:20;;43455:8;44499:803;;44645:84;;-1:-1:-1;;;44645:84:0;;-1:-1:-1;;;;;44645:48:0;;;;;:84;;44694:10;;44706:5;;44713:8;;44723:5;;44645:84;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44645:84:0;;;;;;;;-1:-1:-1;;44645:84:0;;;;;;;;;;;;:::i;:::-;;;44641:650;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45008:13:0;;45004:272;;45051:60;;-1:-1:-1;;;45051:60:0;;20748:2:1;45051: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;;45051:60:0;20546:414:1;45004:272:0;45226:6;45220:13;45211:6;45207:2;45203:15;45196:38;44641:650;-1:-1:-1;;;;;;44779:69:0;;-1:-1:-1;;;44779:69:0;44775:166;;44873:48;;-1:-1:-1;;;44873:48:0;;21167:2:1;44873: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;;44873:48:0;20965:402:1;44775:166:0;44730:226;44641:650;44289:1020;;;;:::o;74953:122::-;75027:5;;-1:-1:-1;;;;;75027:5:0;75013:10;:19;75005:28;;;;;;75062:5;75044:15;;;:5;:15;;;;;:23;;-1:-1:-1;;75044:23:0;;;74953:122::o;60252:106::-;60294:56;60306:1;60309:19;;;;;;;;60323:1;60309:19;;;;;;60326:1;60309:19;;;60330;;;;;;;;60344:1;60330:19;;;;;;60347:1;60330:19;;;60294:11;:56::i;:::-;60252:106::o;86188:1265::-;86373:18;;;;86365:55;;;;-1:-1:-1;;;86365:55:0;;16378:2:1;86365:55:0;;;16360:21:1;16417:2;16397:18;;;16390:30;-1:-1:-1;;;16436:18:1;;;16429:54;16500:18;;86365:55:0;16176:348:1;86365:55:0;86431:23;76514:80;86560:6;:4;:6::i;:::-;86544:24;;;;;;;86603:7;;;;;;;;;;;-1:-1:-1;;;86603:7:0;;;;86481:210;;;;;21631:25:1;;;;21672:18;;;21665:34;;;;86587:25:0;21715:18:1;;;21708:34;86631:13:0;21758:18:1;;;21751:34;86671:4:0;21801:19:1;;;;21794:61;;;;86481:210:0;;;;;;;;;;21603:19:1;;;86481:210:0;;86457:245;;;;;;76734:71;86758:57;;;22097:25:1;-1:-1:-1;;;;;22158:32:1;;22138:18;;;22131:60;22207:18;;;22200:34;;;22250:18;;;;22243:34;;;86758:57:0;;;;;;;;;;22069:19:1;;;86758:57:0;;;86734:92;;;;;;;-1:-1:-1;;;86878:57:0;;;22546:27:1;22589:11;;;22582:27;;;22625:12;;;22618:28;;;86457:245:0;;-1:-1:-1;86734:92:0;-1:-1:-1;;22662:12:1;;86878:57:0;;;-1:-1:-1;;86878:57:0;;;;;;;;;86854:92;;86878:57;86854:92;;;;86957:17;86977:26;;;;;;;;;22912:25:1;;;22985:4;22973:17;;22953:18;;;22946:45;;;;23007:18;;;23000:34;;;23050:18;;;23043:34;;;86854:92:0;;-1:-1:-1;86957:17:0;86977:26;;22884:19:1;;86977:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;86977:26:0;;-1:-1:-1;;86977:26:0;;;-1:-1:-1;;;;;;;87036:23:0;;87014:119;;;;-1:-1:-1;;;87014:119:0;;23290:2:1;87014: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;;87014:119:0;23088:410:1;87014:119:0;-1:-1:-1;;;;;87175:17:0;;;;;;:6;:17;;;;;:19;;;;;;:::i;:::-;;;;;87166:5;:28;87144:120;;;;-1:-1:-1;;;87144:120:0;;23705:2:1;87144: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;;87144:120:0;23503:406:1;87144:120:0;87316:6;87297:15;:25;;87275:121;;;;-1:-1:-1;;;87275:121:0;;24116:2:1;87275: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;;87275:121:0;23914:410:1;87275:121:0;87414:31;87424:9;87435;87414;:31::i;:::-;87407:38;;;;86188:1265;;;;;;;:::o;64870:313::-;64932:9;50920:14;50873:7;64944:22;50873:7;64944:15;:22;:::i;:::-;:29;;;;:::i;:::-;:39;;;;:::i;:::-;64932:51;;64995:6;64991:185;65005:4;:11;65003:1;:13;64991:185;;;65032:9;50873:7;;65044:6;:15;65051:4;65056:1;65051:7;;;;;;;;:::i;:::-;;;;;;;65044:15;;;;;;;;;;;:19;;;:26;;;;:::i;:::-;:33;;;;:::i;:::-;65032:45;;65097:4;65090;:11;65087:81;;;65116:41;65138:4;65143:1;65138:7;;;;;;;;:::i;:::-;;;;;;;50920:14;65116:20;:41::i;:::-;-1:-1:-1;65018:3:0;;;;:::i;:::-;;;;64991:185;;33476:431;33597:1;33566:19;;;:9;:19;;;;;;33532:13;;-1:-1:-1;;;;;33566:19:0;33558:73;;;;-1:-1:-1;;;33558:73:0;;24531:2:1;33558:73:0;;;24513:21:1;24570:2;24550:18;;;24543:30;24609:29;24589:18;;;24582:57;24656:18;;33558:73:0;24329:351:1;33558:73:0;33642:29;33674:16;;;:6;:16;;;;;;;;;33642:48;;;;;;;;;;;;;;;;;;;;;33720:8;;-1:-1:-1;;;;;33720:8:0;33708:31;33681:8;33777:40;33681:8;33801:15;33777:13;:40::i;:::-;33832:12;;;;33871:15;;33708:191;;;;;;-1:-1:-1;;;;;;33708:191:0;;;;;;24916:25:1;;;;24957:18;;;24950:34;;;;25000:18;;;24993:34;33864:23:0;;25043:18:1;;;25036:34;24888:19;;33708:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;33708:191:0;;;;;;;;;;;;:::i;74016:102::-;74066:4;74090:20;74107:1;74090:8;:20::i;75487:722::-;75552:18;;;;:11;:18;;;;;;:23;:40;;;;-1:-1:-1;75580:12:0;;;;:5;:12;;;;;;;;75579:13;75552:40;75544:61;;;;-1:-1:-1;;;75544:61:0;;;;;;;:::i;:::-;75633:3;75624:5;:12;;75616:21;;;;;;75656:37;75675:10;75687:5;75656:18;:37::i;:::-;75648:46;;;;;;75713:35;75732:10;75744:3;75713:18;:35::i;:::-;75705:44;;;;;;75762:29;75794:13;;;:6;:13;;;;;;;;75762:45;;;;;;;;;;;;;;;;;;;;;;;;;;75850:11;;;;;;;;;75818:43;;;;;;;;;;;;;;;;;;;;;;;;75898:15;;75937:12;;75762:45;;75818:43;;75891:23;;;;-1:-1:-1;75937:28:0;:58;;75983:8;:12;;;75937:58;;;75968:8;:12;;;75937:58;76024:19;;;;;;;;-1:-1:-1;76024:19:0;;;;;;;;;;76008:13;;;:6;:13;;;;;:35;;;;-1:-1:-1;;;;;;76008:35:0;-1:-1:-1;;;;;76008:35:0;;;;;;;-1:-1:-1;76008:35:0;;;;;;;76083:19;;;;;;;;;;;;;;;75926:69;;-1:-1:-1;76054:49:0;;76008:13;;76073:8;;76054:11;:49::i;:::-;76114:12;76120:5;76114;:12::i;:::-;76137:64;76150:3;76155:6;76163:3;76168:8;76178:22;76137:12;:64::i;63135:176::-;32253:7;;63238:4;;32253:7;;32252:8;32244:35;;;;-1:-1:-1;;;32244:35:0;;;;;;;:::i;:::-;32290:7;:14;;-1:-1:-1;;32290:14:0;32300:4;32290:14;;;63262:41:::1;63275:6:::0;63283:14;63299:3;63262:12:::1;:41::i;:::-;32327:7:::0;:15;;-1:-1:-1;;32327:15:0;;;63255:48;63135:176;-1:-1:-1;;;;63135:176:0:o;88143:97::-;88202:2;;-1:-1:-1;;;;;88202:2:0;88188:10;:16;88180:32;;;;-1:-1:-1;;;88180:32:0;;;;;;;:::i;:::-;88230:2;;88223:4;:9;;-1:-1:-1;;;;;;88223:9:0;-1:-1:-1;;;;;88230:2:0;;;88223:9;;;;;;88143:97::o;68863:130::-;68934:4;68958:27;68972:8;68982:2;68958:13;:27::i;68656:199::-;68716:4;68737:26;;;:16;:26;;;;;;68767:12;68737:42;68733:56;;;-1:-1:-1;68788:1:0;;68656:199;-1:-1:-1;68656:199:0:o;68733:56::-;68807:40;68821:8;68831:15;68807:13;:40::i;60683:455::-;32253:7;;;;32252:8;32244:35;;;;-1:-1:-1;;;32244:35:0;;;;;;;:::i;:::-;32290:7;:14;;-1:-1:-1;;32290:14:0;32300:4;32290:14;;;;;;:7;60797:16;;;:6:::1;:16;::::0;;;;;;;;60765:48;;;;::::1;::::0;;;;;::::1;;::::0;;;;::::1;::::0;;;::::1;::::0;;;;60834:10;60826:37:::1;;;::::0;-1:-1:-1;;;60826:37:0;;25283:2:1;60826: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;;60826:37:0::1;25081:338:1::0;60826:37:0::1;60928:1;60910:8;:15;;;:19;;;60902:54;;;::::0;-1:-1:-1;;;60902:54:0;;17491:2:1;60902: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;;60902:54:0::1;17289:346:1::0;60902:54:0::1;60990:15;60975:8;:12;;;:30;60967:79;;;;-1:-1:-1::0;;;60967:79:0::1;;;;;;;:::i;:::-;61057:73;61070:8;61080:6;61088:1;61091:8;61101:28;61057:12;:73::i;75083:194::-:0;75156:8;;;;;-1:-1:-1;;;;;75156:8:0;75142:10;:22;;:45;;-1:-1:-1;75182:5:0;;-1:-1:-1;;;;;75182:5:0;75168:10;:19;75142:45;75134:75;;;;-1:-1:-1;;;75134:75:0;;18247:2:1;75134:75:0;;;18229:21:1;18286:2;18266:18;;;18259:30;-1:-1:-1;;;18305:18:1;;;18298:47;18362:18;;75134:75:0;18045:341:1;75134:75:0;75244:21;;;;:11;:21;;;;;;:25;;75268:1;75244:25;:::i;74825:120::-;74898:5;;-1:-1:-1;;;;;74898:5:0;74884:10;:19;74876:28;;;;;;74915:15;;;;:5;:15;;;;;:22;;-1:-1:-1;;74915:22:0;74933:4;74915:22;;;74825:120::o;34811:116::-;-1:-1:-1;;;;;34892:27:0;34868:4;34892:27;;;:19;:27;;;;;;;34811:116::o;40433:989::-;40587:21;;;;:11;:21;;;;;;:26;:46;;;;-1:-1:-1;40618:15:0;;;;:5;:15;;;;;;;;40617:16;40587:46;40579:67;;;;-1:-1:-1;;;40579:67:0;;;;;;;:::i;:::-;40714:12;;-1:-1:-1;;;40714:12:0;;;;40697:13;40706:3;40697:8;:13::i;:::-;:29;;40688:86;;;;-1:-1:-1;;;40688:86:0;;;;;;;:::i;:::-;40793:37;40812:7;40821:8;40793:18;:37::i;:::-;40785:46;;;;;;40913:31;40928:5;40935:8;40913:14;:31::i;:::-;41019:33;41036:5;41043:8;41019:16;:33::i;:::-;41092:63;41112:16;41122:5;41112:9;:16::i;:::-;41130:14;41140:3;41130:9;:14::i;:::-;41146:8;41092:19;:63::i;:::-;41186:26;41198:3;41203:8;41186:11;:26::i;:::-;41298;;;;:16;:26;;;;;;41327:12;41298:41;;41384:30;41315:8;;-1:-1:-1;;;;;41384:30:0;;;;;;;;-1:-1:-1;;;;;;;;;;;41384:30:0;;40433:989;;;;:::o;39426:422::-;39510:4;39543:19;;;:9;:19;;;;;;;;;39660:13;:23;;;;;;-1:-1:-1;;;;;39543:19:0;;;39726:23;;;:16;:23;;;;;39595:17;;;39725:35;;;;;;;;;39543:19;;39595:17;;;;39660:23;;;;39648:35;;39725;;39595:17;;39778:35;;;39796:17;39778:35;:62;;;;39817:23;39778:62;39771:69;39426:422;-1:-1:-1;;;;;;;39426:422:0:o;52506:5883::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52798:5:0;;52720:17;;;;52820:13;;52816:1170;;52962:15;52945:10;:14;;;:32;:57;;;;;53001:1;52981:10;:17;;;:21;;;52945:57;52941:234;;;53037:17;;:28;;50977:14;;53037:28;:::i;:::-;53023:42;;:11;;;;:42;;;;53125:14;;;:32;;53142:15;;53125:32;:::i;:::-;53097:5;:11;;;:62;;;;:::i;:::-;53084:75;;;;52941:234;53210:15;53193:10;:14;;;:32;:57;;;;;53249:1;53229:10;:17;;;:21;;;53193:57;53189:234;;;53285:17;;:28;;50977:14;;53285:28;:::i;:::-;53271:42;;:11;;;;:42;;;;53373:14;;;:32;;53390:15;;53373:32;:::i;:::-;53345:5;:11;;;:62;;;;:::i;:::-;53332:75;;;;53189:234;53691:14;;;;;53677:29;;;;:13;:29;;;;;;53725:14;;;;53677:29;;;;;;-1:-1:-1;53725:19:0;53721:254;;53787:10;:14;;;53769:10;:14;;;:32;53765:195;;;53839:10;53826:23;;53765:195;;;53925:14;;;;;53911:29;;;;:13;:29;;;;;;;;;;-1:-1:-1;53765:195:0;54024:66;;;;;;;;53998:23;54024:66;;;;;;;54054:15;54024:66;;;;;;;54076:12;54024:66;;;;54105:10;;54101:77;;-1:-1:-1;54145:21:0;;;;:13;:21;;;;;;;;;54132:34;;;;;;;;;;;;;;;-1:-1:-1;;;54132:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54101:77;54211:13;;;;:10;54188:20;54554:15;:31;-1:-1:-1;54550:160:0;;;54684:13;;;;54666:31;;:15;:31;:::i;:::-;54646:14;;;;54631:29;;:12;:29;:::i;:::-;54617:44;;51036:7;54617:44;:::i;:::-;54616:82;;;;:::i;:::-;54602:96;;54550:160;54949:8;50873:7;54961:22;50873:7;54961:15;:22;:::i;:::-;54960:31;;;;:::i;:::-;54949:42;;55011:6;55006:1384;55027:3;55023:1;:7;55006:1384;;;55234:11;50873:7;55234:11;;:::i;:::-;;;55264:14;55311:15;55305:3;:21;55301:168;;;55357:15;55351:21;;55301:168;;;-1:-1:-1;55431:18:0;;;;:13;:18;;;;;;;;55301:168;55539:21;55545:15;55539:3;:21;:::i;:::-;55506:10;:16;;;:56;;;;:::i;:::-;55487:75;;:10;;:75;;;;;:::i;:::-;;;;;-1:-1:-1;55581:16:0;;;:27;;55601:7;;55581:16;:27;;55601:7;;55581:27;:::i;:::-;;;;;;;;55631:15;;55649:1;55631:19;;;55627:127;;-1:-1:-1;55627:127:0;;55733:1;55715:19;;55627:127;55795:1;55776:10;:16;;;:20;;;55772:147;;;55898:1;55879:16;;;:20;55772:147;55977:13;;;;:19;;;56079:21;;;55955:3;;-1:-1:-1;55955:3:0;;51036:7;;56073:27;;55955:3;56073:27;:::i;:::-;56058:43;;:11;:43;:::i;:::-;56057:58;;;;:::i;:::-;56032:18;:22;;;:83;;;;:::i;:::-;56015:14;;;:100;56134:11;56144:1;56134:11;;:::i;:::-;;;56175:15;56168:3;:22;56164:211;;;-1:-1:-1;56232:12:0;56215:14;;;:29;56267:5;;56164:211;56321:21;;;;:13;:21;;;;;;;;;:34;;;;;;-1:-1:-1;;;;;56321:34:0;;;-1:-1:-1;;;56321:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55032:3:0;;;:::i;:::-;;;55006:1384;;;-1:-1:-1;;56413:5:0;:14;;;56496:13;;56492:483;;56704:5;:11;;;56690:5;:11;;;:25;;;;:::i;:::-;56669:10;:16;;:47;;;;;;;:::i;:::-;;;;;-1:-1:-1;56764:10:0;;56751;;:23;;56764:10;56751:23;:::i;:::-;56731:44;;:10;;:44;;;;;:::i;:::-;;;;;;;;56794:16;;;;56813:1;56794:20;;;56790:81;;-1:-1:-1;56790:81:0;;56854:1;56835:16;;;:20;56790:81;56907:1;56889:10;:15;;;:19;;;56885:79;;;56947:1;56929:19;;56885:79;57037:21;;;;:13;:21;;;;;;;;;:34;;;;;;-1:-1:-1;;;;;57037:34:0;;;-1:-1:-1;;;57037:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;57088:13;;57084:1298;;57328:15;57311:10;:14;;;:32;57307:402;;;57458:11;;;;57444:25;;;;:::i;:::-;;;57510:10;:14;;;57492:10;:14;;;:32;57488:145;;;57563:11;;;;57549:25;;;;:::i;:::-;;;57488:145;57665:14;;;;;57651:29;;;;:13;:29;;;;;;:42;;-1:-1:-1;;;;;;57651:42:0;-1:-1:-1;;;;;57651:42:0;;;;;57307:402;57746:15;57729:10;:14;;;:32;57725:344;;;57803:10;:14;;;57786:10;:14;;;:31;57782:209;;;57856:11;;;;57842:25;;;;:::i;:::-;57943:14;;;;;57929:29;;;;:13;:29;;;;;;:42;;-1:-1:-1;;;;;;57929:42:0;-1:-1:-1;;;;;57929:42:0;;;;;;-1:-1:-1;57782:209:0;58123:15;58141:26;;;:16;:26;;;;;;:30;;58170:1;58141:30;:::i;:::-;58123:48;;58217:10;58188:16;:26;58205:8;58188:26;;;;;;;;;;;:39;;;;58253:15;58242:5;:8;;:26;;;;;58295:12;58283:5;:9;;:24;;;;;58365:5;58322:18;:28;58341:8;58322:28;;;;;;;;;;;58351:10;58322:40;;;;;;;:::i;:::-;:48;;;;;;-1:-1:-1;;;;;58322:48:0;;;-1:-1:-1;;;58322:48:0;;;;:40;;;;;;;;;:48;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57084:1298:0;52651:5738;;;;;;;;;52506:5883;;;:::o;49830:486::-;49888:40;49907:10;49919:8;49888:18;:40::i;:::-;49880:85;;;;-1:-1:-1;;;49880:85:0;;27854:2:1;49880:85:0;;;27836:21:1;;;27873:18;;;27866:30;27932:34;27912:18;;;27905:62;27984:18;;49880:85:0;27652:356:1;49880:85:0;49978:13;34542:19;;;:9;:19;;;;;;-1:-1:-1;;;;;34542:19:0;;50051:29;;34542:19;50051:7;:29::i;:::-;50122:59;50142:16;50152:5;50142:9;:16::i;:::-;50168:1;50172:8;50122:19;:59::i;:::-;50217:38;50234:10;50246:8;50217:16;:38::i;:::-;50271:37;;50299:8;;50295:1;;-1:-1:-1;;;;;50271:37:0;;;-1:-1:-1;;;;;;;;;;;50271:37:0;50295:1;;50271:37;49869:447;49830:486;:::o;68117:531::-;68187:4;68218:26;;;:16;:26;;;;;;68259:11;68255:386;;68294:1;68287:8;;;;;68255:386;68328:23;68354:28;;;:18;:28;;;;;68383:6;68354:36;;;;;;;:::i;:::-;68328:62;;;;;;;;68354:36;;;;;;;;;68328:62;;;;;;;;-1:-1:-1;;;68328:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68450:34:0;;68457:2;68450:34;:::i;:::-;68424:10;:16;;;:61;;;;:::i;:::-;68405:80;;:10;;:80;;;;;:::i;:::-;;;;;;;;68504:15;;68522:1;68504:19;;;68500:79;;-1:-1:-1;68500:79:0;;68562:1;68544:19;;68500:79;68612:15;68605:23;;;-1:-1:-1;68593:36:0;;-1:-1:-1;68593:36:0;85361:441;85563:23;85589:20;85599:9;85589;:20::i;:::-;-1:-1:-1;;;;;85622:21:0;;;;;;;:10;:21;;;;;;:33;;-1:-1:-1;;;;;;85622:33:0;;;;;;;;;;85673:54;;85563:46;;-1:-1:-1;85622:33:0;85673:54;;;;;;85622:21;85673:54;85738:56;85756:9;85767:15;85784:9;85738:17;:56::i;61406:1059::-;61493:4;61513:14;61531:3;61513:21;61510:948;;;61565:5;;61558:61;;-1:-1:-1;;;61558:61:0;;61585:10;61558:61;;;28525:34:1;61605:4:0;28575:18:1;;;28568:43;28627:18;;;28620:34;;;61565:5:0;;;;-1:-1:-1;;;;;61565:5:0;;61558:26;;28460:18:1;;61558:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61549:88;;;;-1:-1:-1;;;61549:88:0;;28867:2:1;61549:88:0;;;28849:21:1;28906:2;28886:18;;;28879:30;-1:-1:-1;;;28925:18:1;;;28918:41;28976:18;;61549:88:0;28665:335:1;61549:88:0;61665:5;;61658:37;;-1:-1:-1;;;61658:37:0;;-1:-1:-1;;;;;14317:32:1;;;61658:37:0;;;14299:51:1;14366:18;;;14359:34;;;61665:5:0;;;;;;;;61658:22;;14272:18:1;;61658:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61649:65;;;;-1:-1:-1;;;61649:65:0;;29207:2:1;61649:65:0;;;29189:21:1;29246:2;29226:18;;;29219:30;-1:-1:-1;;;29265:18:1;;;29258:42;29317:18;;61649:65:0;29005:336:1;61649:65:0;-1:-1:-1;61733:1:0;61726:8;;61510:948;61799:12;;-1:-1:-1;;;61799:12:0;;;;61782:13;61791:3;61782:8;:13::i;:::-;:29;;61773:86;;;;-1:-1:-1;;;61773:86:0;;;;;;;:::i;:::-;61871:16;50873:7;;61891:32;61909:14;61891:15;:32;:::i;:::-;61890:41;;;;:::i;:::-;:48;;;;:::i;:::-;61871:67;;62006:1;61997:6;:10;61989:19;;;;;;62070:15;62056:11;:29;62048:80;;;;-1:-1:-1;;;62048:80:0;;29548:2:1;62048:80:0;;;29530:21:1;29587:2;29567:18;;;29560:30;29626:34;29606:18;;;29599:62;-1:-1:-1;;;29677:18:1;;;29670:36;29723:19;;62048:80:0;29346:402:1;62048:80:0;62163:25;50920:14;62163:15;:25;:::i;:::-;62148:11;:40;;62140:84;;;;-1:-1:-1;;;62140:84:0;;19640:2:1;62140:84:0;;;19622:21:1;19679:2;19659:18;;;19652:30;19718:33;19698:18;;;19691:61;19769:18;;62140:84:0;19438:355:1;62140:84:0;62240:7;;62238:9;;;;;:::i;:::-;;;;-1:-1:-1;62275:7:0;;62294:20;62300:3;62275:7;62294:5;:20::i;:::-;-1:-1:-1;62372:16:0;;;;:6;:16;;;;;;;;;62328:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;62341:8;;62351:6;;62359:11;;62328:12;:91::i;:::-;62438:8;-1:-1:-1;62431:15:0;;-1:-1:-1;62431:15:0;72472:791;72543:4;72560:23;72586:5;72560:31;;72602:8;50873:7;;72614:10;:13;;;:20;;;;:::i;:::-;72613:29;;;;:::i;:::-;72602:40;;72658:6;72653:472;72674:3;72670:1;:7;72653:472;;;72699:11;50873:7;72699:11;;:::i;:::-;;;72725:14;72768:1;72762:3;:7;72758:124;;;72796:1;72790:7;;72758:124;;;-1:-1:-1;72848:18:0;;;;:13;:18;;;;;;;;72758:124;72954:13;;;;72948:19;;:3;:19;:::i;:::-;72915:10;:16;;;:54;;;;:::i;:::-;72896:73;;:10;;:73;;;;;:::i;:::-;;;;;-1:-1:-1;72988:8:0;;;72984:54;;;73017:5;;;72984:54;73072:7;73052:10;:16;;:27;;;;;;;:::i;:::-;;;;;-1:-1:-1;;73094:13:0;;;:19;;;72679:3;;;:::i;:::-;;;72653:472;;;;73159:1;73141:10;:15;;;:19;;;73137:71;;;73195:1;73177:19;;73137:71;-1:-1:-1;73238:15:0;-1:-1:-1;;;;;73225:30:0;;72472:791;-1:-1:-1;;;72472:791:0:o;69303:1690::-;69379:4;69517:12;69507:6;:22;;69500:30;;;;:::i;:::-;69569:9;69605:26;;;:16;:26;;;;;;69569:9;69642:391;69663:3;69659:1;:7;69642:391;;;69758:4;69750;:12;69746:58;;69783:5;;69746:58;69818:9;69850:1;69831:11;69838:4;69831;:11;:::i;:::-;:15;;69845:1;69831:15;:::i;:::-;69830:21;;;;:::i;:::-;69870:28;;;;:18;:28;;;;;69818:33;;-1:-1:-1;69912:6:0;;69818:33;69870:34;;;;;;;:::i;:::-;;;;:38;;;:48;69866:156;;69946:4;69939:11;;69866:156;;;69998:8;70005:1;69998:4;:8;:::i;:::-;69991:15;;69866:156;-1:-1:-1;69668:3:0;;;:::i;:::-;;;69642:391;;;-1:-1:-1;70045:19:0;70067:28;;;:18;:28;;;;;70096:4;70067:34;;;;;;;:::i;:::-;70045:56;;;;;;;;70067:34;;;;;;;;;70045:56;;;;;;;;-1:-1:-1;;;70045:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70131:5;;70045:56;;-1:-1:-1;;70161:36:0;70179:6;70131:5;70161:17;:36::i;:::-;70208:20;70231:21;;;:13;:21;;;;;;;;70208:44;;;;;;;;;;;;;;;-1:-1:-1;;;70208:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70147:50;;-1:-1:-1;70208:20:0;70317:18;;;70313:311;;;70352:20;70375:13;70352:20;70389:10;:6;70398:1;70389:10;:::i;:::-;70375:25;;;;;;;;;;;;;;-1:-1:-1;70375:25:0;70352:48;;;;;;;;;;;;;;;-1:-1:-1;;;70352:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70439:11;;;70352:48;;-1:-1:-1;70425:25:0;;70439:11;70425:25;:::i;:::-;70415:35;;70484:7;:10;;;70471:7;:10;;;:23;;;;:::i;:::-;70465:29;;70337:169;70313:311;;;70552:11;;;;70537:26;;:12;:26;:::i;:::-;70527:36;;70602:7;:10;;;70584:15;:28;;;;:::i;:::-;70578:34;;70313:311;70652:10;;;;70677:12;;70673:99;;70753:7;70737;:11;;;70728:6;:20;;;;:::i;:::-;70721:28;;:3;:28;:::i;:::-;70720:40;;;;:::i;:::-;70706:54;;;;:::i;:::-;;;70673:99;70841:9;;;;70828:22;;:10;:22;:::i;:::-;70799:6;:12;;;:53;;;;:::i;:::-;70784:68;;:6;;:68;;;;;:::i;:::-;;;;;;;;70867:11;;70882:1;70867:16;;;;-1:-1:-1;70863:123:0;;-1:-1:-1;;70920:11:0;;-1:-1:-1;;;;;70907:26:0;;-1:-1:-1;70900:33:0;;-1:-1:-1;;;;;;70900:33:0;70863:123;70973:1;70966:8;;;;;;;;;;;;;58732:1363;59013:6;;58967:14;;59041:22;59057:6;59013;59041:22;:::i;:::-;59032:6;:31;-1:-1:-1;;;;;;;;;;;;;;;;;59155:15:0;;59172:12;;;;;59136:14;;;59116:69;;;;;59278:41;;59311:6;;59155:8;;59278:41;;59311:6;;59278:41;:::i;:::-;;;;;-1:-1:-1;59334:16:0;;59330:75;;59367:12;;;:26;;;59330:75;59415:16;;;;:6;:16;;;;;;;;:27;;;;-1:-1:-1;;;;;;59415:27:0;-1:-1:-1;;;;;59415:27:0;;;;;;;;;;-1:-1:-1;59415:27:0;;;;59694:43;59415:16;59716:10;59415:27;59694:11;:43::i;:::-;59765:10;59790:11;;;;;:53;;-1:-1:-1;59821:22:0;59805:12;:38;;;;;;;;:::i;:::-;;;59790:53;59786:149;;;59874:5;;59867:55;;-1:-1:-1;;;59867:55:0;;-1:-1:-1;;;;;28543:15:1;;;59867:55:0;;;28525:34:1;59908:4:0;28575:18:1;;;28568:43;28627:18;;;28620:34;;;59874:5:0;;;;;;;;59867:26;;28460:18:1;;59867:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59860:63;;;;:::i;:::-;59982:8;:12;;;59958:4;-1:-1:-1;;;;;59950:76:0;;59964:8;59974:6;59996:12;60010:15;59950:76;;;;;;;;;:::i;:::-;;;;;;;;60042:45;60049:13;60064:22;60080:6;60049:13;60064:22;:::i;:::-;60042:45;;;15152:25:1;;;15208:2;15193:18;;15186:34;;;;15125:18;60042:45:0;;;;;;;58924:1171;;;;58732:1363;;;;;:::o;67254:583::-;67333:4;;67412:9;67333:4;67432:376;67453:3;67449:1;:7;67432:376;;;67548:4;67540;:12;67536:58;;67573:5;;67536:58;67608:9;67640:1;67621:11;67628:4;67621;:11;:::i;:::-;:15;;67635:1;67621:15;:::i;:::-;67620:21;;;;:::i;:::-;67660:19;;;;:13;:19;;;;;:23;;;67608:33;;-1:-1:-1;67660:33:0;-1:-1:-1;67656:141:0;;67721:4;67714:11;;67656:141;;;67773:8;67780:1;67773:4;:8;:::i;:::-;67766:15;;67656:141;-1:-1:-1;67458:3:0;;;:::i;:::-;;;67432:376;;;-1:-1:-1;67825:4:0;;67254:583;-1:-1:-1;;;;67254:583:0:o;38756:324::-;38894:19;;;;:9;:19;;;;;;-1:-1:-1;;;;;38894:29:0;;;:19;;:29;38887:37;;;;:::i;:::-;38974:1;38939:23;;;:13;:23;;;;;;-1:-1:-1;;;;;38939:23:0;:37;38935:138;;39059:1;39025:23;;;:13;:23;;;;;:36;;-1:-1:-1;;;;;;39025:36:0;;;38935:138;38756:324;;:::o;49400:422::-;49538:19;;;;:9;:19;;;;;;-1:-1:-1;;;;;49538:28:0;;;:19;;:28;49531:36;;;;:::i;:::-;49637:1;49607:19;;;:9;:19;;;;;:32;;-1:-1:-1;;;;;;49607:32:0;;;49696:42;49722:5;49617:8;49696:25;:42::i;:::-;-1:-1:-1;;;;;49783:26:0;;;;;;:19;:26;;;;;:31;;49813:1;;49783:26;:31;;49813:1;;49783:31;:::i;:::-;;;;-1:-1:-1;;;;49400:422:0:o;80517:2026::-;80661:6;-1:-1:-1;;;;;80651:16:0;:6;-1:-1:-1;;;;;80651:16:0;;;:32;;;;;80682:1;80671:8;:12;80651:32;80647:1889;;;-1:-1:-1;;;;;80704:20:0;;;80700:837;;-1:-1:-1;;;;;80764:22:0;;80745:16;80764:22;;;:14;:22;;;;;;;;;80832:13;:135;;-1:-1:-1;;;;;80936:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;80832:135;;;-1:-1:-1;;;;;80869:19:0;;;;;;:11;:19;;;;;;80889:13;80901:1;80889:9;:13;:::i;:::-;80869:34;;;;;;;;;;;;;;;:43;;80832:135;80805:162;;80986:20;81009:34;81036:6;81009:26;:34::i;:::-;-1:-1:-1;;;;;81089:19:0;;81062:24;81089:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;80986:57;;-1:-1:-1;81089:83:0;;;;;81240:223;81261:16;;81257:20;;81240:223;;;81307:8;81318:9;81328:1;81318:12;;;;;;;;:::i;:::-;;;;;;;;;81307:23;;81364:8;81357:3;:15;81353:91;;81401:19;;;;;;;-1:-1:-1;81401:19:0;;;;;;;;;;81353:91;-1:-1:-1;81279:3:0;;;;:::i;:::-;;;;81240:223;;;-1:-1:-1;81508:13:0;:9;81520:1;81508:13;:::i;:::-;-1:-1:-1;;;;;81483:22:0;;;;;;:14;:22;;;;;:38;;-1:-1:-1;;81483:38:0;;;;;;;;;;;;-1:-1:-1;;;;80700:837:0;-1:-1:-1;;;;;81557:20:0;;;81553:972;;-1:-1:-1;;;;;81617:22:0;;81598:16;81617:22;;;:14;:22;;;;;;;;;81685:13;:135;;-1:-1:-1;;;;;81789:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;81685:135;;;-1:-1:-1;;;;;81722:19:0;;;;;;:11;:19;;;;;;81742:13;81754:1;81742:9;:13;:::i;:::-;81722:34;;;;;;;;;;;;;;;:43;;81685:135;81658:162;;81839:20;81862:34;81889:6;81862:26;:34::i;:::-;-1:-1:-1;;;;;81942:19:0;;81915:24;81942:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;82121:16;;81839:57;;-1:-1:-1;81942:83:0;;;;;76956:4;;82121:20;;:16;:20;:::i;:::-;:37;;82091:146;;;;-1:-1:-1;;;82091:146:0;;;;;;;:::i;:::-;82261:6;82256:152;82277:16;;82273:20;;82256:152;;;82323:8;82334:9;82344:1;82334:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;82369:19;;;;;;;;;;;;;;;;-1:-1:-1;82295:3:0;;;;:::i;:::-;;;;82256:152;;;-1:-1:-1;82426:24:0;;;;;;;;-1:-1:-1;82426:24:0;;;;;;;;;;;;82496:13;;:9;;:13;:::i;:::-;-1:-1:-1;;;;;82471:22:0;;;;;;:14;:22;;;;;:38;;;;;;;-1:-1:-1;;82471:38:0;;;;;;;;;-1:-1:-1;;;;80517:2026:0;;;:::o;46925:402::-;47085:1;47054:19;;;:9;:19;;;;;;-1:-1:-1;;;;;47054:19:0;:33;47047:41;;;;:::i;:::-;47128:19;;;;:9;:19;;;;;:25;;-1:-1:-1;;;;;;47128:25:0;-1:-1:-1;;;;;47128:25:0;;;;;47210:35;47128:25;:19;47210:20;:35::i;:::-;-1:-1:-1;;;;;47290:24:0;;;;;;:19;:24;;;;;:29;;47318:1;;47290:24;:29;;47318:1;;47290:29;:::i;83027:2326::-;83218:6;-1:-1:-1;;;;;83208:16:0;:6;-1:-1:-1;;;;;83208:16:0;;83204:2142;;-1:-1:-1;;;;;83245:20:0;;;83241:852;;-1:-1:-1;;;;;83305:22:0;;83286:16;83305:22;;;:14;:22;;;;;;;;;83373:13;:135;;-1:-1:-1;;;;;83477:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;83373:135;;;-1:-1:-1;;;;;83410:19:0;;;;;;:11;:19;;;;;;83430:13;83442:1;83430:9;:13;:::i;:::-;83410:34;;;;;;;;;;;;;;;:43;;83373:135;83346:162;;83527:20;83550:34;83577:6;83550:26;:34::i;:::-;-1:-1:-1;;;;;83630:19:0;;83603:24;83630:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;83527:57;;-1:-1:-1;83630:83:0;;;;;83788:231;83809:16;;83805:20;;83788:231;;;83855:8;83866:9;83876:1;83866:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;83905:14;;;:9;:14;;;;;;;;83866:12;;-1:-1:-1;;;;;;83905:14:0;;;:23;;;;83901:99;;83957:19;;;;;;;-1:-1:-1;83957:19:0;;;;;;;;;;83901:99;-1:-1:-1;83827:3:0;;;;:::i;:::-;;;;83788:231;;;-1:-1:-1;84064:13:0;:9;84076:1;84064:13;:::i;:::-;-1:-1:-1;;;;;84039:22:0;;;;;;:14;:22;;;;;:38;;-1:-1:-1;;84039:38:0;;;;;;;;;;;;-1:-1:-1;;;;83241:852:0;-1:-1:-1;;;;;84113:20:0;;;84109:1226;;-1:-1:-1;;;;;84173:22:0;;84154:16;84173:22;;;:14;:22;;;;;;;;;84241:13;:135;;-1:-1:-1;;;;;84345:19:0;;;;;;:11;:19;;;;;;;;:22;;;;;;;;:31;;84241:135;;;-1:-1:-1;;;;;84278:19:0;;;;;;:11;:19;;;;;;84298:13;84310:1;84298:9;:13;:::i;:::-;84278:34;;;;;;;;;;;;;;;:43;;84241:135;84214:162;;84395:20;84418:34;84445:6;84418:26;:34::i;:::-;-1:-1:-1;;;;;84498:19:0;;;84471:24;84498:19;;;:11;:19;;;;;;;;:74;;;;;;;;;;84623:26;;;;;:19;:26;;;;;;84698:16;;84395:57;;-1:-1:-1;84498:83:0;;;;;76956:4;;84698:34;;84623:26;;84698:34;:::i;:::-;:51;;84668:160;;;;-1:-1:-1;;;84668:160:0;;;;;;;:::i;:::-;84885:6;84880:152;84901:16;;84897:20;;84880:152;;;84947:8;84958:9;84968:1;84958:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;84993:19;;;;;;;;;;;;;;;;-1:-1:-1;84919:3:0;;;;:::i;:::-;;;;84880:152;;;;85097:6;85092:169;85113:15;85109:1;:19;85092:169;;;-1:-1:-1;;;;;85169:27:0;;85158:8;85169:27;;;:20;:27;;;;;;;;:30;;;;;;;;85222:19;;;;;;;;;;;;;;;;85197:1;85130:3;85197:1;85130:3;:::i;:::-;;;;85092:169;;;-1:-1:-1;85306:13:0;:9;85318:1;85306:13;:::i;:::-;-1:-1:-1;;;;;85281:22:0;;;;;;:14;:22;;;;;:38;;;;;;;-1:-1:-1;;85281:38:0;;;;;;;;;-1:-1:-1;;;;;83027:2326:0;;;:::o;47667:426::-;47728:4;-1:-1:-1;;;;;47796:17:0;;47789:25;;;;:::i;:::-;47856:57;47884:1;47888:14;47898:3;47888:9;:14::i;47856:57::-;47986:26;47998:3;48003:8;47986:11;:26::i;:::-;48028:35;;48054:8;;-1:-1:-1;;;;;48028:35:0;;;48045:1;;-1:-1:-1;;;;;;;;;;;48028:35:0;48045:1;;48028:35;-1:-1:-1;48081:4:0;47667:426;;;;:::o;48273:1013::-;48377:18;48416:1;48398:15;48407:5;48398:8;:15::i;:::-;:19;;;;:::i;:::-;48428:18;48449:27;;;:17;:27;;;;;;48377:40;;-1:-1:-1;48493:30:0;;;48489:790;;;-1:-1:-1;;;;;48584:27:0;;48629:1;48584:27;;;:20;:27;;;;;;;;:42;;;;;;;;:46;;;48686:27;;;:17;:27;;;;;:31;48489:790;;;-1:-1:-1;;;;;48769:27:0;;;;48750:16;48769:27;;;:20;:27;;;;;;;;:42;;;;;;;;;;;48892;;;;;;:56;;;49004:30;;:17;:30;;;;;;:46;;;;49134;;;;49236:27;;;;;:31;48273:1013::o;82551:468::-;-1:-1:-1;;;;;82745:23:0;;82654:6;82745:23;;;:14;:23;;;;;;82696:15;;82745:23;;82799:17;;;;;:97;;-1:-1:-1;;;;;;82833:20:0;;;;;;:11;:20;;;;;82886:10;;82854:17;82870:1;82854:13;:17;:::i;:::-;82833:39;;;;;;;;;;;;;-1:-1:-1;82833:39:0;:49;:63;82799:97;82781:231;;;82930:17;82946:1;82930:13;:17;:::i;46580:238::-;46658:18;46679:13;46688:3;46679:8;:13::i;:::-;-1:-1:-1;;;;;46705:25:0;;;;;;;:20;:25;;;;;;;;:40;;;;;;;;:51;;;46767:27;;;:17;:27;;;;;;:43;;;;-1:-1:-1;46580: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;:::-;10815:5;10191:635;-1:-1:-1;;;;;10191:635:1:o;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;29753:127::-;29814:10;29809:3;29805:20;29802:1;29795:31;29845:4;29842:1;29835:15;29869:4;29866:1;29859:15;29885:557;30129:25;;;30185:2;30170:18;;30163:34;;;30116:3;30101:19;;30227:1;30216:13;;30206:144;;30272:10;30267:3;30263:20;30260:1;30253:31;30307:4;30304:1;30297:15;30335:4;30332:1;30325:15;30206:144;30381:2;30366:18;;30359:34;;;;30424:2;30409:18;30402:34;29885:557;;-1:-1:-1;;29885:557:1:o;30447:228::-;30486:3;30514:10;30551:2;30548:1;30544:10;30581:2;30578:1;30574:10;30612:3;30608:2;30604:12;30599:3;30596:21;30593:47;;;30620:18;;:::i;:::-;30656:13;;30447:228;-1:-1:-1;;;;30447:228:1:o;30680:399::-;30882:2;30864:21;;;30921:2;30901:18;;;30894:30;30960:34;30955:2;30940:18;;30933:62;-1:-1:-1;;;31026:2:1;31011:18;;31004:33;31069:3;31054:19;;30680:399::o
Swarm Source
ipfs://d2ffb784f3a3c51df6bf36e0bcac00d5ba3249877112db76334fc59a2a2f92bd
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.