Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
VeSixUpgradeable
Compiler Version
v0.8.27+commit.40a35a09
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2025-03-03 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC 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); } pragma solidity ^0.8.20; /** * @dev Required interface of an ERC-721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC-721 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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 address zero. * * 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); } pragma solidity ^0.8.20; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } pragma solidity ^0.8.20; /** * @title ERC-721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC-721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } pragma solidity ^0.8.20; /** * @dev Library that provide common ERC-721 utility functions. * * See https://eips.ethereum.org/EIPS/eip-721[ERC-721]. * * _Available since v5.1._ */ library ERC721Utils { /** * @dev Performs an acceptance check for the provided `operator` by calling {IERC721-onERC721Received} * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`). * * The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA). * Otherwise, the recipient must implement {IERC721Receiver-onERC721Received} and return the acceptance magic value to accept * the transfer. */ function checkOnERC721Received( address operator, address from, address to, uint256 tokenId, bytes memory data ) internal { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { // Token rejected revert IERC721Errors.ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { // non-IERC721Receiver implementer revert IERC721Errors.ERC721InvalidReceiver(to); } else { assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } } } } } pragma solidity ^0.8.20; /** * @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] * ```solidity * 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 Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 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. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._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. * * 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. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * 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. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._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() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @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. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } } pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } } // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } } pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @dev Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 1); } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } } pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165Upgradeable is Initializable, IERC165 { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } pragma solidity ^0.8.20; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC-721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721, IERC721Metadata, IERC721Errors { using Strings for uint256; /// @custom:storage-location erc7201:openzeppelin.storage.ERC721 struct ERC721Storage { // Token name string _name; // Token symbol string _symbol; mapping(uint256 tokenId => address) _owners; mapping(address owner => uint256) _balances; mapping(uint256 tokenId => address) _tokenApprovals; mapping(address owner => mapping(address operator => bool)) _operatorApprovals; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC721")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant ERC721StorageLocation = 0x80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300; function _getERC721Storage() private pure returns (ERC721Storage storage $) { assembly { $.slot := ERC721StorageLocation } } /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { ERC721Storage storage $ = _getERC721Storage(); $._name = name_; $._symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual returns (uint256) { ERC721Storage storage $ = _getERC721Storage(); if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return $._balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { ERC721Storage storage $ = _getERC721Storage(); return $._name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { ERC721Storage storage $ = _getERC721Storage(); return $._symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual returns (string memory) { _requireOwned(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { ERC721Storage storage $ = _getERC721Storage(); return $._operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC-721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); return $._owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); return $._tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if: * - `spender` does not have approval from `owner` for `tokenId`. * - `spender` does not have approval to manage all of `owner`'s assets. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { ERC721Storage storage $ = _getERC721Storage(); unchecked { $._balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { $._balances[from] -= 1; } } if (to != address(0)) { unchecked { $._balances[to] += 1; } } $._owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), address(0), to, tokenId, data); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC-721 standard to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { ERC721Storage storage $ = _getERC721Storage(); // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } $._tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { ERC721Storage storage $ = _getERC721Storage(); if (operator == address(0)) { revert ERC721InvalidOperator(operator); } $._operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } } pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); } pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } 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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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); } } } pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20PermitUpgradeable token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token)); } } pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { /// @custom:storage-location erc7201:openzeppelin.storage.Ownable struct OwnableStorage { address _owner; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300; function _getOwnableStorage() private pure returns (OwnableStorage storage $) { assembly { $.slot := OwnableStorageLocation } } /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ function __Ownable_init(address initialOwner) internal onlyInitializing { __Ownable_init_unchained(initialOwner); } function __Ownable_init_unchained(address initialOwner) internal onlyInitializing { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { OwnableStorage storage $ = _getOwnableStorage(); return $._owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { OwnableStorage storage $ = _getOwnableStorage(); address oldOwner = $._owner; $._owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } pragma solidity 0.8.27; interface IRewardsDistributor { function claim(uint256 tokenId) external returns (uint256); function earned(uint256 tokenId) external view returns (uint256); function checkpoint_token() external; function checkpoint_total_supply() external; function getClaimableRewards(uint256 tokenId) external view returns ( address[] memory tokens, uint256[] memory amounts, uint256[] memory periods ); function getProxyCaller() external view returns (address); } //@author 0xPhant0m based on Andre Cronje's voteEscrow contract for Solidly pragma solidity 0.8.27; contract VeSixUpgradeable is ERC721Upgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable, OwnableUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; // Custom errors error InvalidAmount(); error InvalidDuration(); error TransferFailed(); error NotTokenOwner(); error LockNotExpired(); error ZeroReward(); error InvalidToken(); error InvalidArtProxy(); error ZeroAddress(); error DeadlineExpired(); error LockExpired(); error ExceedsMaxLocks(); error InvalidRewardRate(); error SlippageExceeded(); error MaxRewardRateExceeded(); error TokenNotExists(); error LockNotExists(); error MultiplierTooHigh(); error InvalidMultiplier(); error ArithmeticError(); struct Point { int128 bias; // Current farming power int128 slope; // Farming power decrease rate uint32 ts; // Timestamp of point uint32 blk; // Block number } struct LockedBalance { int128 amount; uint32 end; } struct LockPosition { uint128 amount; uint128 slope; uint32 endTime; uint32 lastUpdate; } // Constants uint32 private constant MAXTIME = 180 days; uint32 private constant WEEK = 7 * 86400; uint128 private constant MAX_MULTIPLIER = 4e18; uint128 private constant BASE_MULTIPLIER = 1e18; uint128 private constant PRECISION = 1e18; uint8 private constant MAX_LOCKS_PER_USER = 100; uint128 private constant MAX_REWARD_RATE = 1000e18; int128 private constant iMAXTIME = int128(uint128(MAXTIME)); // State variables IERC20Upgradeable private _lockedToken; IRewardsDistributor private _distributor; uint32 private _nextTokenId; mapping(uint256 => LockPosition) public _locks; mapping(address => uint8) public _userLockCount; // Point history state mapping(uint32 => Point) public pointHistory; uint32 public epoch; mapping(uint256 => uint32) public userPointEpoch; mapping(uint256 => mapping(uint32 => Point)) public userPointHistory; mapping(uint32 => int128) public slopeChanges; address public artProxy; uint32 MAX_BLOCK_DRIFT = 15; uint128 private _totalWeightedSupply; // Emergency recovery address private _emergencyRecoveryAddress; bool private _emergencyMode; // Events event Deposit( address indexed user, uint256 indexed tokenId, uint128 amount, uint32 lockTime ); event Withdraw( address indexed user, uint256 indexed tokenId, uint128 amount ); event RewardClaimed( address indexed user, uint256 indexed tokenId, uint128 reward ); event EmergencyModeEnabled(address recoveryAddress); event EmergencyWithdraw( address indexed user, uint256 indexed tokenId, uint128 amount ); event LockExtended( address indexed user, uint256 indexed tokenId, uint32 newEndTime, uint128 newMultiplier ); event AmountIncreased( address indexed user, uint256 indexed tokenId, uint128 additionalAmount, uint128 newTotalAmount, uint128 newMultiplier ); // Event to track point fixes event PointsFixed(uint256 indexed tokenId, uint32 fromEpoch, uint32 toEpoch); // Storage gap for future upgrades uint256[49] private __gap; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( address lockedToken_, address emergencyRecovery, string memory name, string memory symbol ) public initializer { if (lockedToken_ == address(0) || emergencyRecovery == address(0)) revert ZeroAddress(); __ERC721_init(name, symbol); __ReentrancyGuard_init(); __Pausable_init(); __Ownable_init(msg.sender); _pause(); _lockedToken = IERC20Upgradeable(lockedToken_); _emergencyRecoveryAddress = emergencyRecovery; // Initialize point history pointHistory[0].blk = uint32(block.number); pointHistory[0].ts = uint32(block.timestamp); } function setDistributor(address distributor_) external onlyOwner { if (distributor_ == address(0)) revert ZeroAddress(); if (address(_distributor) != address(0)) revert("Distributor already set"); _distributor = IRewardsDistributor(distributor_); } // Modifiers modifier validDeadline(uint256 deadline) { if (block.timestamp > deadline) revert DeadlineExpired(); _; } modifier poke(uint256 tokenId) { LockPosition memory lock = _locks[tokenId]; if (lock.amount > 0 && uint32(block.timestamp) < lock.endTime) { // Calculate time-based parameters based on the corrected calculation uint32 timeLeft = lock.endTime - uint32(block.timestamp); // Get the current multiplier from the corrected algorithm uint256 timeRatio = (uint256(timeLeft) * PRECISION) / MAXTIME; uint256 multiplierCalc = BASE_MULTIPLIER + (uint256(MAX_MULTIPLIER - BASE_MULTIPLIER) * timeRatio) / PRECISION; uint128 newMultiplier = uint128(multiplierCalc); if (newMultiplier > MAX_MULTIPLIER) newMultiplier = MAX_MULTIPLIER; if (newMultiplier < BASE_MULTIPLIER) newMultiplier = BASE_MULTIPLIER; // Calculate proper slope based on the corrected calculation uint256 slopeCalc = (uint256(lock.amount) / MAXTIME) * PRECISION; uint128 newSlope = uint128(slopeCalc); // Only update if slope is different or it's been a while since last update if (lock.slope != newSlope || (block.timestamp - lock.lastUpdate) > 1 days) { // Record previous weighted supply value uint128 oldMultiplier; if (lock.slope > 0) { uint256 oldTimeRatio = (uint256(timeLeft) * PRECISION) / MAXTIME; uint256 oldMultiplierCalc = BASE_MULTIPLIER + (uint256(MAX_MULTIPLIER - BASE_MULTIPLIER) * oldTimeRatio) / PRECISION; oldMultiplier = uint128(oldMultiplierCalc); if (oldMultiplier > MAX_MULTIPLIER) oldMultiplier = MAX_MULTIPLIER; if (oldMultiplier < BASE_MULTIPLIER) oldMultiplier = BASE_MULTIPLIER; } else { oldMultiplier = BASE_MULTIPLIER; } uint256 oldWeightedAmount = (uint256(lock.amount) * oldMultiplier) / PRECISION; uint256 newWeightedAmount = (uint256(lock.amount) * newMultiplier) / PRECISION; // Update weighted supply by the difference if (newWeightedAmount > oldWeightedAmount) { uint256 increase = newWeightedAmount - oldWeightedAmount; _totalWeightedSupply += uint128(increase); } else if (oldWeightedAmount > newWeightedAmount) { uint256 decrease = oldWeightedAmount - newWeightedAmount; if (decrease > _totalWeightedSupply) { _totalWeightedSupply = 0; // Safeguard against underflow } else { _totalWeightedSupply -= uint128(decrease); } } // Checkpoint to record the update _checkpoint( tokenId, LockedBalance(int128(uint128(lock.amount)), lock.endTime), LockedBalance(int128(uint128(lock.amount)), lock.endTime) ); // Update lock parameters _locks[tokenId].slope = newSlope; _locks[tokenId].lastUpdate = uint32(block.timestamp); } } _; } function getCurrentMultiplier(uint256 tokenId) public view returns (uint128) { LockPosition memory lock = _locks[tokenId]; if (uint32(block.timestamp) >= lock.endTime) return BASE_MULTIPLIER; // Calculate time-based multiplier - should be proportional to lock duration uint32 timeLeft = lock.endTime - uint32(block.timestamp); // Calculate how much of the maximum time is left (as a ratio) // This ensures amount doesn't affect multiplier, only duration does uint256 timeRatio = (uint256(timeLeft) * PRECISION) / MAXTIME; // Apply linear scaling between BASE_MULTIPLIER (1x) and MAX_MULTIPLIER (4x) uint256 multiplierCalc = BASE_MULTIPLIER + (uint256(MAX_MULTIPLIER - BASE_MULTIPLIER) * timeRatio) / PRECISION; uint128 multiplier = uint128(multiplierCalc); if (multiplier > MAX_MULTIPLIER) return MAX_MULTIPLIER; if (multiplier < BASE_MULTIPLIER) return BASE_MULTIPLIER; return multiplier; } function _checkpoint( uint256 tokenId, LockedBalance memory oldLocked, LockedBalance memory newLocked ) internal { _checkpointGlobal(); if (tokenId != 0) { _checkpointToken( tokenId, oldLocked, newLocked ); } } function _checkpointGlobal() internal { uint32 _epoch = epoch; Point memory lastPoint; // Get the last point if (_epoch > 0) { lastPoint = pointHistory[_epoch - 1]; } else { lastPoint = Point({ bias: 0, slope: 0, ts: uint32(block.timestamp), blk: uint32(block.number) }); } uint32 lastCheckpoint = lastPoint.ts; // Calculate block slope for time interpolation uint128 blockSlope = 0; if (uint32(block.timestamp) > lastCheckpoint) { blockSlope = uint128((PRECISION * (block.number - lastPoint.blk)) / (block.timestamp - lastPoint.ts)); } // Process weekly checkpoints lastPoint = _processWeeklyCheckpoints( lastPoint, lastCheckpoint, blockSlope, _epoch ); epoch = _epoch + 1; pointHistory[_epoch] = lastPoint; // Ensure we're not losing precision in the global state if (lastPoint.bias < 0) { lastPoint.bias = 0; } } function _processWeeklyCheckpoints( Point memory lastPoint, uint32 lastCheckpoint, uint128 blockSlope, uint32 _epoch ) internal returns (Point memory) { uint32 ti = (lastCheckpoint / WEEK) * WEEK; uint32 t = uint32(block.timestamp); for (uint256 i = 0; i < 255;) { ti += WEEK; if (ti > t) { lastPoint.bias -= lastPoint.slope * int128(uint128(t - lastCheckpoint)); lastPoint.ts = t; lastPoint.blk = uint32(block.number); break; } lastPoint.bias -= lastPoint.slope * int128(uint128(ti - lastCheckpoint)); lastPoint.slope += slopeChanges[ti]; lastPoint.ts = ti; lastPoint.blk = uint32(lastPoint.blk + (uint256(blockSlope) * (ti - lastPoint.ts)) / PRECISION); pointHistory[_epoch + 1 + uint32(i)] = lastPoint; lastCheckpoint = ti; unchecked { ++i; } } return lastPoint; } function _checkpointToken( uint256 tokenId, LockedBalance memory oldLocked, LockedBalance memory newLocked ) internal { Point memory uOld; Point memory uNew; _processLockPoint(oldLocked, uOld); _processLockPoint(newLocked, uNew); _processTokenSlopeChanges(oldLocked, newLocked, uOld.slope, uNew.slope); uint32 userEpoch = userPointEpoch[tokenId] + 1; userPointEpoch[tokenId] = userEpoch; uNew.ts = uint32(block.timestamp); uNew.blk = uint32(block.number); userPointHistory[tokenId][userEpoch] = uNew; } function _processLockPoint( LockedBalance memory locked, Point memory point ) internal view returns (bool) { if (locked.end <= uint32(block.timestamp) || locked.amount == 0) return false; uint256 timeLeft = uint256(locked.end - uint32(block.timestamp)); timeLeft = timeLeft > MAXTIME ? MAXTIME : timeLeft; uint256 multiplier = BASE_MULTIPLIER + ((timeLeft * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / MAXTIME); multiplier = multiplier > MAX_MULTIPLIER ? MAX_MULTIPLIER : multiplier < BASE_MULTIPLIER ? BASE_MULTIPLIER : multiplier; uint256 scaledAmount = uint256(uint128(locked.amount)); point.bias = int128(uint128((scaledAmount * multiplier) / PRECISION)); point.slope = int128(uint128((scaledAmount * PRECISION) / MAXTIME)); return true; } function _processTokenSlopeChanges( LockedBalance memory oldLocked, LockedBalance memory newLocked, int128 oldSlope, int128 newSlope ) internal { // Handle old lock slope changes if (oldLocked.end > uint32(block.timestamp)) { // Remove the old slope change int128 oldDslope = slopeChanges[oldLocked.end]; oldDslope += oldSlope; // Add because we're removing negative slope // If the new lock ends at the same time, we need to account for its slope too if (newLocked.end == oldLocked.end) { oldDslope -= newSlope; // Subtract new slope that will decrease at this time } slopeChanges[oldLocked.end] = oldDslope; } // Handle new lock slope changes if (newLocked.end > uint32(block.timestamp)) { if (newLocked.end > oldLocked.end) { // Only record new slope changes if the end time is different int128 newDslope = slopeChanges[newLocked.end]; newDslope -= newSlope; // This slope will decrease at the new end time slopeChanges[newLocked.end] = newDslope; } } } function _beforeTokenTransfer( address from, uint256 tokenId ) internal { if (from != address(0) && address(_distributor) != address(0) && _ownerOf(tokenId) != address(0)) { if (_distributor.earned(tokenId) > 0) { _distributor.claim(tokenId); } } } function transferFrom(address from, address to, uint256 tokenId) public virtual override { _beforeTokenTransfer(from, tokenId); super.transferFrom(from,to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { _beforeTokenTransfer(from, tokenId); super.safeTransferFrom(from, to, tokenId, data); } function withdraw(uint256 tokenId) external nonReentrant { address owner = _ownerOf(tokenId); if (owner == address(0)) revert TokenNotExists(); if (owner != msg.sender) revert NotTokenOwner(); LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0) revert LockNotExists(); if (uint32(block.timestamp) < lock.endTime) revert LockNotExpired(); uint128 amount = lock.amount; // For expired locks, just subtract balance from weighted supply if (amount > _totalWeightedSupply) { _totalWeightedSupply = 0; } else { _totalWeightedSupply -= amount; } // Clear lock state delete _locks[tokenId]; // Create checkpoint data LockedBalance memory oldLock = LockedBalance({ amount: int128(uint128(amount)), end: lock.endTime }); // Checkpoint after clearing lock _checkpoint(tokenId, oldLock, LockedBalance(0, 0)); // Clean up remaining state delete userPointEpoch[tokenId]; // Transfer tokens before burning NFT _lockedToken.safeTransfer(msg.sender, amount); // Burn NFT last _burn(tokenId); unchecked { _userLockCount[msg.sender]--; } emit Withdraw(msg.sender, tokenId, amount); } function _calculateLockParameters( uint128 amount, uint32 lockDuration, uint128 minMultiplier ) internal pure returns (uint128 slope, uint128 multiplier) { // First divide by MAXTIME to avoid overflow uint256 slopeCalc = uint256(amount) / MAXTIME; // Then multiply by PRECISION slopeCalc = slopeCalc * PRECISION; require(slopeCalc <= type(uint128).max, "Slope overflow"); slope = uint128(slopeCalc); // Calculate multiplier multiplier = _calculateMultiplier(slope, lockDuration); if (multiplier > MAX_MULTIPLIER) revert MultiplierTooHigh(); if (multiplier < minMultiplier) revert SlippageExceeded(); } // Helper function to update weighted supply correctly for the poke operation // This is a differential update based on the change in multiplier function _updateWeightedSupply(uint256 tokenId, uint128 amount, uint128 newMultiplier) internal { // First calculate current weighted amount based on old multiplier // Since we don't store the old multiplier directly, we need to recalculate based on slope LockPosition memory lock = _locks[tokenId]; uint128 oldMultiplier = lock.slope > 0 ? uint128(BASE_MULTIPLIER + (uint256(lock.slope) * (lock.endTime - uint32(block.timestamp)))) : BASE_MULTIPLIER; if (oldMultiplier > MAX_MULTIPLIER) oldMultiplier = MAX_MULTIPLIER; if (oldMultiplier < BASE_MULTIPLIER) oldMultiplier = BASE_MULTIPLIER; // Calculate old and new weighted amounts uint256 oldWeightedAmount = (uint256(amount) * uint256(oldMultiplier)) / PRECISION; uint256 newWeightedAmount = (uint256(amount) * uint256(newMultiplier)) / PRECISION; // Calculate the difference (can be positive or negative) if (newWeightedAmount > oldWeightedAmount) { uint256 increase = newWeightedAmount - oldWeightedAmount; if (increase > type(uint128).max) revert ArithmeticError(); _totalWeightedSupply += uint128(increase); } else if (oldWeightedAmount > newWeightedAmount) { uint256 decrease = oldWeightedAmount - newWeightedAmount; if (decrease > _totalWeightedSupply) { _totalWeightedSupply = 0; // Safeguard against underflow } else { _totalWeightedSupply -= uint128(decrease); } } // If equal, no change needed } function createLock( uint128 amount, uint32 lockDuration, uint256 deadline, uint128 minMultiplier ) external nonReentrant whenNotPaused validDeadline(deadline) returns (uint256 tokenId) { if (amount == 0) revert InvalidAmount(); if (lockDuration == 0 || lockDuration > MAXTIME) revert InvalidDuration(); if (_userLockCount[msg.sender] >= MAX_LOCKS_PER_USER) revert ExceedsMaxLocks(); uint32 unlockTime = uint32(block.timestamp) + lockDuration; (uint128 slope, uint128 multiplier) = _calculateLockParameters(amount, lockDuration, minMultiplier); // Create new lock balance LockedBalance memory newLock = LockedBalance({ amount: int128(uint128(amount)), end: unlockTime }); // Checkpoint before modifying state _checkpoint(0, LockedBalance(0, 0), newLock); // Transfer tokens using SafeERC20 uint256 balanceBefore = _lockedToken.balanceOf(address(this)); _lockedToken.safeTransferFrom(msg.sender, address(this), amount); if (_lockedToken.balanceOf(address(this)) != balanceBefore + amount) revert TransferFailed(); unchecked { tokenId = _nextTokenId++; _userLockCount[msg.sender]++; } _safeMint(msg.sender, tokenId); _locks[tokenId] = LockPosition({ amount: amount, endTime: unlockTime, lastUpdate: uint32(block.timestamp), slope: slope }); _updateWeightedSupply(tokenId, amount, multiplier); emit Deposit(msg.sender, tokenId, amount, unlockTime); } function extendLock( uint256 tokenId, uint32 additionalDuration, uint256 deadline, uint128 minMultiplier ) external nonReentrant whenNotPaused validDeadline(deadline) poke(tokenId) { if (ownerOf(tokenId) != msg.sender) revert NotTokenOwner(); LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0) revert LockNotExists(); // Calculate new end time uint32 newEndTime = lock.endTime + additionalDuration; uint32 totalRemainingDuration = newEndTime - uint32(block.timestamp); if (totalRemainingDuration > MAXTIME) revert InvalidDuration(); // Calculate new slope and multiplier with proper scaling uint128 newSlope = _calculateNewSlope(lock.amount); uint128 multiplier = _calculateMultiplier(newSlope, totalRemainingDuration); if (multiplier < minMultiplier) revert SlippageExceeded(); // Update weighted supply _updateWeightedSupply(tokenId, lock.amount, multiplier); // Checkpoint _checkpoint( tokenId, LockedBalance({ amount: int128(uint128(lock.amount)), end: lock.endTime }), LockedBalance({ amount: int128(uint128(lock.amount)), end: newEndTime }) ); // Update lock state _locks[tokenId] = LockPosition({ amount: lock.amount, endTime: newEndTime, lastUpdate: uint32(block.timestamp), slope: newSlope }); emit LockExtended(msg.sender, tokenId, newEndTime, multiplier); } function _calculateNewSlope(uint128 amount) private pure returns (uint128) { // First divide by MAXTIME to avoid overflow uint256 slopeCalc = uint256(amount) / MAXTIME; // Then multiply by PRECISION slopeCalc = slopeCalc * PRECISION; require(slopeCalc <= type(uint128).max, "Slope too high"); return uint128(slopeCalc); } function _calculateMultiplier(uint128 slope, uint32 duration) internal pure returns (uint128) { // Special case: If slope is 0, return base multiplier to avoid division by zero if (slope == 0) return BASE_MULTIPLIER; // Calculate time ratio first to avoid overflow uint256 timeRatio = (uint256(duration) * PRECISION) / MAXTIME; // Calculate multiplier based on time ratio uint256 multiplier = BASE_MULTIPLIER + ((timeRatio * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / PRECISION); if (multiplier > MAX_MULTIPLIER) return MAX_MULTIPLIER; if (multiplier < BASE_MULTIPLIER) return BASE_MULTIPLIER; return uint128(multiplier); } // Helper function for increasing lock amount logic function _processIncreaseLock( uint256 tokenId, uint128 additionalAmount, uint128 minMultiplier ) private { LockPosition storage lock = _locks[tokenId]; // Get old values and calculate new values uint128 oldAmount = lock.amount; uint128 newAmount = oldAmount + additionalAmount; uint32 endTime = lock.endTime; uint32 remainingDuration = endTime - uint32(block.timestamp); // Calculate new slope and multiplier uint128 newSlope = _calculateNewSlope(newAmount); uint128 multiplier = _calculateMultiplier(newSlope, remainingDuration); // Get current multiplier and use higher value uint128 currentMultiplier = getCurrentMultiplier(tokenId); multiplier = multiplier > currentMultiplier ? multiplier : currentMultiplier; // Slippage check for non-dust amounts if (additionalAmount > PRECISION / 1000 && multiplier < minMultiplier) { revert SlippageExceeded(); } // Checkpoint with correct LockedBalance structs _checkpoint( tokenId, LockedBalance({ amount: int128(uint128(oldAmount)), end: endTime }), LockedBalance({ amount: int128(uint128(newAmount)), end: endTime }) ); // Update lock state lock.amount = newAmount; lock.slope = newSlope; lock.lastUpdate = uint32(block.timestamp); // Update weighted supply _updateWeightedSupply(tokenId, additionalAmount, multiplier); emit AmountIncreased(msg.sender, tokenId, additionalAmount, newAmount, multiplier); } function increaseLockAmount( uint256 tokenId, uint128 additionalAmount, uint256 deadline, uint128 minMultiplier ) external nonReentrant whenNotPaused validDeadline(deadline) poke(tokenId) { // Basic validations if (ownerOf(tokenId) != tx.origin) {if (ownerOf(tokenId) != msg.sender) revert NotTokenOwner();} if (additionalAmount == 0) revert InvalidAmount(); // Check if lock exists and not expired LockPosition storage lock = _locks[tokenId]; if (lock.amount == 0) revert LockNotExists(); if (uint32(block.timestamp) >= lock.endTime) revert LockExpired(); // Transfer tokens uint256 balanceBefore = _lockedToken.balanceOf(address(this)); _lockedToken.safeTransferFrom(msg.sender, address(this), additionalAmount); if (_lockedToken.balanceOf(address(this)) != balanceBefore + additionalAmount) revert TransferFailed(); // Process the lock increase in a separate function _processIncreaseLock(tokenId, additionalAmount, minMultiplier); } function getTotalFarmingPower(uint32 timestamp) public view returns (uint128) { Point memory lastPoint = pointHistory[epoch]; return uint128(_supplyAt(lastPoint, timestamp)); } function _supplyAt(Point memory point, uint32 t) internal view returns (uint128) { uint32 ti = (point.ts / WEEK) * WEEK; for (uint256 i = 0; i < 255;) { ti += WEEK; if (ti > t) { point.bias -= point.slope * int128(uint128(t - point.ts)); break; } point.bias -= point.slope * int128(uint128(ti - point.ts)); point.slope += slopeChanges[ti]; point.ts = ti; unchecked { ++i; } } if (point.bias < 0) point.bias = 0; return uint128(uint256(uint128(point.bias))); } function merge( uint256[] calldata tokenIds, uint256 deadline ) external nonReentrant whenNotPaused validDeadline(deadline) { if (tokenIds.length < 2) revert InvalidAmount(); uint128 totalAmount; uint32 latestEndTime; // First pass: validate ownership and calculate totals for (uint256 i = 0; i < tokenIds.length; i++) { if (ownerOf(tokenIds[i]) != msg.sender) revert NotTokenOwner(); LockPosition memory lock = _locks[tokenIds[i]]; totalAmount += lock.amount; if (lock.endTime > latestEndTime) { latestEndTime = lock.endTime; } } // Create new merged position uint32 remainingDuration = latestEndTime - uint32(block.timestamp); if (remainingDuration > MAXTIME) revert InvalidDuration(); // Use veRAM's approach for slope calculation uint128 newSlope = uint128((uint256(totalAmount) * PRECISION) / MAXTIME); uint256 newTokenId = ++_nextTokenId; _safeMint(msg.sender, newTokenId); // Checkpoint and cleanup old positions for (uint256 i = 0; i < tokenIds.length; i++) { uint256 tokenId = tokenIds[i]; LockPosition memory oldLock = _locks[tokenId]; LockedBalance memory oldLockedBalance = LockedBalance({ amount: int128(uint128(oldLock.amount)), end: oldLock.endTime }); _checkpoint(tokenId, oldLockedBalance, LockedBalance(0, 0)); delete _locks[tokenId]; _burn(tokenId); } // Create new lock LockedBalance memory newLock = LockedBalance({ amount: int128(uint128(totalAmount)), end: latestEndTime }); _checkpoint(newTokenId, LockedBalance(0, 0), newLock); _locks[newTokenId] = LockPosition({ amount: totalAmount, endTime: latestEndTime, lastUpdate: uint32(block.timestamp), slope: newSlope }); unchecked { _userLockCount[msg.sender] = uint8(_userLockCount[msg.sender] - uint8(tokenIds.length) + 1); } emit Deposit(msg.sender, newTokenId, totalAmount, latestEndTime); } function getFarmingPower(uint256 tokenId, uint32 timestamp) public view returns (uint128) { uint32 userEpoch = userPointEpoch[tokenId]; if (userEpoch == 0) return 0; LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0 || timestamp >= lock.endTime) return 0; for (uint32 i = userEpoch; i >= 1; i--) { Point memory point = userPointHistory[tokenId][i]; if (point.ts <= timestamp) { uint256 timeRatio = (uint256(lock.endTime - timestamp) * PRECISION) / MAXTIME; uint256 multiplier = BASE_MULTIPLIER + ((timeRatio * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / PRECISION); multiplier = multiplier > MAX_MULTIPLIER ? MAX_MULTIPLIER : multiplier < BASE_MULTIPLIER ? BASE_MULTIPLIER : multiplier; uint256 power = (uint256(uint128(point.bias)) * multiplier) / PRECISION; return power > type(uint128).max ? type(uint128).max : uint128(power); } } return 0; } function getExpectedMultiplier(uint128 amount, uint32 duration) public pure returns (uint128) { if (duration == 0 || duration > MAXTIME) revert InvalidDuration(); if (amount == 0) revert InvalidAmount(); // Combine _calculateNewSlope and _calculateMultiplier logic here uint256 slope = (uint256(amount) / MAXTIME) * PRECISION; if (slope == 0) return BASE_MULTIPLIER; uint256 timeRatio = (uint256(duration) * PRECISION) / MAXTIME; uint256 multiplier = BASE_MULTIPLIER + ((timeRatio * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / PRECISION); return multiplier > MAX_MULTIPLIER ? MAX_MULTIPLIER : multiplier < BASE_MULTIPLIER ? BASE_MULTIPLIER : uint128(multiplier); } // Remove redundant pokeLock function since _pokeLockImplementation exists function _pokeLockImplementation(uint256 tokenId) internal poke(tokenId) { // The poke modifier does all the work } // Simplify getMinMultiplier function getMinMultiplier(uint128 amount, uint32 lockDuration) public view returns (uint128) { uint32 minDuration = lockDuration > MAX_BLOCK_DRIFT ? lockDuration - MAX_BLOCK_DRIFT : lockDuration; return getExpectedMultiplier(amount, minDuration); } // Emergency functions function enableEmergencyMode() external onlyOwner { _emergencyMode = true; _pause(); emit EmergencyModeEnabled(_emergencyRecoveryAddress); } function emergencyWithdraw(uint256 tokenId) external nonReentrant { require(_emergencyMode, "Not in emergency mode"); if (ownerOf(tokenId) != msg.sender) revert NotTokenOwner(); LockPosition memory lock = _locks[tokenId]; uint128 amount = lock.amount; delete _locks[tokenId]; _burn(tokenId); unchecked { _userLockCount[msg.sender]--; } _lockedToken.safeTransfer(msg.sender, amount); emit EmergencyWithdraw(msg.sender, tokenId, amount); } function unPause () external onlyOwner { _unpause(); } // View functions function getUserLockCount(address user) external view returns (uint8) { return _userLockCount[user]; } function lockedToken() external view returns (IERC20Upgradeable) { return _lockedToken; } function isEmergencyMode() external view returns (bool) { return _emergencyMode; } function totalWeightedSupply() external view returns (uint128) { return _totalWeightedSupply; } function setArtProxy(address _artProxy) external onlyOwner { if (_artProxy == address(0)) revert ZeroAddress(); artProxy = _artProxy; } function tokensForOwner(address owner) external view returns(uint256[] memory tokenIds) { uint8 count = _userLockCount[owner]; tokenIds = new uint256[](count); if (count == 0) return tokenIds; uint256 currentIndex = 0; for (uint256 id = 0; id < _nextTokenId; id++) { if (_ownerOf(id) == owner) { tokenIds[currentIndex] = id; currentIndex++; if (currentIndex >= count) break; } } return tokenIds; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (_ownerOf(tokenId) == address(0)) revert TokenNotExists(); if (artProxy == address(0)) revert InvalidArtProxy(); // Delegate tokenURI call to art proxy (bool success, bytes memory data) = artProxy.staticcall( abi.encodeWithSignature("tokenURI(uint256)", tokenId) ); require(success, "Art proxy call failed"); return abi.decode(data, (string)); } function createLockFor( address recipient, uint128 amount, uint32 lockDuration, uint256 deadline, uint128 minMultiplier ) external nonReentrant whenNotPaused validDeadline(deadline) returns (uint256 tokenId) { if (amount == 0) revert InvalidAmount(); if (lockDuration == 0 || lockDuration > MAXTIME) revert InvalidDuration(); if (recipient == address(0)) revert ZeroAddress(); if (_userLockCount[recipient] >= MAX_LOCKS_PER_USER) revert ExceedsMaxLocks(); uint32 unlockTime = uint32(block.timestamp) + lockDuration; (uint128 slope, uint128 multiplier) = _calculateLockParameters(amount, lockDuration, minMultiplier); // Create new lock balance LockedBalance memory newLock = LockedBalance({ amount: int128(uint128(amount)), end: unlockTime }); // Checkpoint before modifying state _checkpoint(0, LockedBalance(0, 0), newLock); // Transfer tokens using SafeERC20 uint256 balanceBefore = _lockedToken.balanceOf(address(this)); _lockedToken.safeTransferFrom(msg.sender, address(this), amount); if (_lockedToken.balanceOf(address(this)) != balanceBefore + amount) revert TransferFailed(); unchecked { tokenId = _nextTokenId++; _userLockCount[recipient]++; } _safeMint(recipient, tokenId); _locks[tokenId] = LockPosition({ amount: amount, endTime: unlockTime, lastUpdate: uint32(block.timestamp), slope: slope }); _updateWeightedSupply(tokenId, amount, multiplier); emit Deposit(recipient, tokenId, amount, unlockTime); } function fixHistoricalPoints(uint256[] calldata tokenIds, uint256 batchSize) external { require(batchSize > 0 && batchSize <= 20, "Invalid batch size"); for (uint256 i = 0; i < batchSize && i < tokenIds.length;) { uint256 tokenId = tokenIds[i]; // Early returns for invalid cases if (_ownerOf(tokenId) == address(0) || userPointEpoch[tokenId] == 0) { unchecked { ++i; } continue; } LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0) { unchecked { ++i; } continue; } // Calculate base values once uint128 slope = uint128((lock.amount * PRECISION) / MAXTIME); uint32 userEpoch = userPointEpoch[tokenId]; // Update points for (uint32 currentEpoch = 1; currentEpoch <= userEpoch;) { Point storage point = userPointHistory[tokenId][currentEpoch]; if (point.ts == 0) { unchecked { ++currentEpoch; } continue; } // Calculate time-based multiplier uint32 timeLeft = lock.endTime > point.ts ? lock.endTime - point.ts : 0; timeLeft = timeLeft > MAXTIME ? MAXTIME : timeLeft; uint256 multiplier = BASE_MULTIPLIER + ((timeLeft * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / MAXTIME); // Update point values point.slope = int128(slope); point.bias = int128(uint128((lock.amount * multiplier) / PRECISION)); // Update slope changes for next point if (currentEpoch < userEpoch) { Point memory nextPoint = userPointHistory[tokenId][currentEpoch + 1]; if (nextPoint.ts > 0) { slopeChanges[nextPoint.ts] = nextPoint.slope - point.slope; } } unchecked { ++currentEpoch; } } unchecked { ++i; } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArithmeticError","type":"error"},{"inputs":[],"name":"DeadlineExpired","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"ExceedsMaxLocks","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidArtProxy","type":"error"},{"inputs":[],"name":"InvalidDuration","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidMultiplier","type":"error"},{"inputs":[],"name":"InvalidRewardRate","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"LockExpired","type":"error"},{"inputs":[],"name":"LockNotExists","type":"error"},{"inputs":[],"name":"LockNotExpired","type":"error"},{"inputs":[],"name":"MaxRewardRateExceeded","type":"error"},{"inputs":[],"name":"MultiplierTooHigh","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotTokenOwner","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"SlippageExceeded","type":"error"},{"inputs":[],"name":"TokenNotExists","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroReward","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"additionalAmount","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"newTotalAmount","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"newMultiplier","type":"uint128"}],"name":"AmountIncreased","type":"event"},{"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":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"lockTime","type":"uint32"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recoveryAddress","type":"address"}],"name":"EmergencyModeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"newEndTime","type":"uint32"},{"indexed":false,"internalType":"uint128","name":"newMultiplier","type":"uint128"}],"name":"LockExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"fromEpoch","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"toEpoch","type":"uint32"}],"name":"PointsFixed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"reward","type":"uint128"}],"name":"RewardClaimed","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_locks","outputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint128","name":"slope","type":"uint128"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"lastUpdate","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_userLockCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","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":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint32","name":"lockDuration","type":"uint32"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint128","name":"minMultiplier","type":"uint128"}],"name":"createLock","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint32","name":"lockDuration","type":"uint32"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint128","name":"minMultiplier","type":"uint128"}],"name":"createLockFor","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableEmergencyMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"additionalDuration","type":"uint32"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint128","name":"minMultiplier","type":"uint128"}],"name":"extendLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"batchSize","type":"uint256"}],"name":"fixHistoricalPoints","outputs":[],"stateMutability":"nonpayable","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":"tokenId","type":"uint256"}],"name":"getCurrentMultiplier","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint32","name":"duration","type":"uint32"}],"name":"getExpectedMultiplier","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"}],"name":"getFarmingPower","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint32","name":"lockDuration","type":"uint32"}],"name":"getMinMultiplier","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"timestamp","type":"uint32"}],"name":"getTotalFarmingPower","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserLockCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"additionalAmount","type":"uint128"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint128","name":"minMultiplier","type":"uint128"}],"name":"increaseLockAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lockedToken_","type":"address"},{"internalType":"address","name":"emergencyRecovery","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"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":[],"name":"isEmergencyMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedToken","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"merge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","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":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"pointHistory","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint32","name":"ts","type":"uint32"},{"internalType":"uint32","name":"blk","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"_artProxy","type":"address"}],"name":"setArtProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"distributor_","type":"address"}],"name":"setDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"slopeChanges","outputs":[{"internalType":"int128","name":"","type":"int128"}],"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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensForOwner","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeightedSupply","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"userPointEpoch","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint32","name":"","type":"uint32"}],"name":"userPointHistory","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint32","name":"ts","type":"uint32"},{"internalType":"uint32","name":"blk","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052606d805463ffffffff60a01b1916600f60a01b1790553480156024575f5ffd5b50602b602f565b60df565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615607e5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460dc5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615fbf806100ec5f395ff3fe608060405234801561000f575f5ffd5b5060043610610297575f3560e01c806375619ab511610161578063bcc00225116100ca578063df0c78ef11610084578063df0c78ef14610758578063df2151571461076b578063e58f59471461077e578063e985e9c5146107a3578063f2fde38b146107b6578063f7b188a5146107c9575f5ffd5b8063bcc00225146106e2578063beb8310914610704578063c5b1c7d014610717578063c87b56dd1461071f578063d89dd26914610732578063ddacc94a14610745575f5ffd5b806395d89b411161011b57806395d89b411461065157806397612d4b146106595780639b7d02ad1461066c578063a22cb465146106a9578063b88d4fde146106bc578063bbe33ea5146106cf575f5ffd5b806375619ab51461053457806389f839c6146105475780638b25e8c1146105ca5780638da5cb5b146105dd5780638ff42490146105e5578063900cf0cf1461062c575f5ffd5b8063268dc199116102035780635594a045116101bd5780635594a045146104b3578063586c2600146104c65780635c975abb146104fb5780636352211e1461050657806370a0823114610519578063715018a61461052c575f5ffd5b8063268dc199146104215780632a90752d146104465780632e1a7d4d146104675780632e720f7d1461047a57806342842e0e1461048d5780635312ea8e146104a0575f5ffd5b80631d237a49116102545780631d237a491461033e5780631f5ab022146103c35780632016a0d2146103d657806320a194b8146103e957806323b872dd146103fb57806325f521e41461040e575f5ffd5b806301ffc9a71461029b57806306fdde03146102c3578063081812fc146102d8578063095ea7b3146102f85780630f45cc811461030d57806313de148b1461031e575b5f5ffd5b6102ae6102a9366004615550565b6107d1565b60405190151581526020015b60405180910390f35b6102cb610822565b6040516102ba9190615599565b6102eb6102e63660046155ab565b6108bf565b6040516102ba91906155c2565b61030b6103063660046155f1565b6108d3565b005b6064546001600160a01b03166102eb565b61033161032c366004615619565b6108e2565b6040516102ba9190615632565b61039061034c366004615687565b606b60209081525f928352604080842090915290825290208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60408051600f95860b81529390940b602084015263ffffffff9182169383019390935290911660608201526080016102ba565b61030b6103d13660046156c7565b6109d6565b61030b6103e43660046157cd565b6111b2565b606f54600160a01b900460ff166102ae565b61030b610409366004615850565b6113a9565b61030b61041c36600461588a565b6113c3565b606e546001600160801b03165b6040516001600160801b0390911681526020016102ba565b6104596104543660046158fd565b61177e565b6040519081526020016102ba565b61030b6104753660046155ab565b611b6a565b61030b610488366004615619565b611dfd565b61030b61049b366004615850565b611e4e565b61030b6104ae3660046155ab565b611e68565b606d546102eb906001600160a01b031681565b6104e86104d4366004615957565b606c6020525f9081526040902054600f0b81565b604051600f9190910b81526020016102ba565b60325460ff166102ae565b6102eb6105143660046155ab565b611ffb565b610459610527366004615619565b612005565b61030b61205a565b61030b610542366004615619565b61206d565b6105936105553660046155ab565b60666020525f9081526040902080546001909101546001600160801b0380831692600160801b9004169063ffffffff80821691600160201b90041684565b604080516001600160801b03958616815294909316602085015263ffffffff918216928401929092521660608201526080016102ba565b61042e6105d83660046155ab565b612111565b6102eb61226f565b6103906105f3366004615957565b60686020525f908152604090208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60695461063c9063ffffffff1681565b60405163ffffffff90911681526020016102ba565b6102cb61229d565b61042e610667366004615957565b6122b9565b61069761067a366004615619565b6001600160a01b03165f9081526067602052604090205460ff1690565b60405160ff90911681526020016102ba565b61030b6106b736600461597d565b612325565b61030b6106ca3660046159b2565b612330565b61030b6106dd36600461588a565b612346565b6106976106f0366004615619565b60676020525f908152604090205460ff1681565b61030b610712366004615a1c565b61277f565b61030b612e73565b6102cb61072d3660046155ab565b612edd565b61042e610740366004615a3f565b613030565b61042e610753366004615687565b613192565b61042e610766366004615a3f565b6133f5565b610459610779366004615a67565b61343f565b61063c61078c3660046155ab565b606a6020525f908152604090205463ffffffff1681565b6102ae6107b1366004615a91565b6137e0565b61030b6107c4366004615619565b61381d565b61030b613857565b5f6001600160e01b031982166380ac58cd60e01b148061080157506001600160e01b03198216635b5e139f60e01b145b8061081c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60605f61082d613867565b9050805f01805461083d90615ab9565b80601f016020809104026020016040519081016040528092919081815260200182805461086990615ab9565b80156108b45780601f1061088b576101008083540402835291602001916108b4565b820191905f5260205f20905b81548152906001019060200180831161089757829003601f168201915b505050505091505090565b5f6108c98261388b565b5061081c826138c2565b6108de8282336138e9565b5050565b6001600160a01b0381165f9081526067602052604090205460609060ff16806001600160401b038111156109185761091861570a565b604051908082528060200260200182016040528015610941578160200160208202803683370190505b5091508060ff165f036109545750919050565b5f805b606554600160a01b900463ffffffff168110156109ce57846001600160a01b0316610981826138f6565b6001600160a01b0316036109c657808483815181106109a2576109a2615af1565b6020908102919091010152816109b781615b19565b9250508260ff168210156109ce575b600101610957565b505050919050565b6109de61391d565b6109e6613974565b8180421115610a0857604051631ab7da6b60e01b815260040160405180910390fd5b5f85815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b9004909216606083015286919015801590610a855750806040015163ffffffff164263ffffffff16105b15610ea2575f428260400151610a9b9190615b31565b90505f62ed4e00610aba670de0b6b3a764000063ffffffff8516615b4d565b610ac49190615b78565b90505f670de0b6b3a764000082610ae382673782dace9d900000615b8b565b6001600160801b0316610af69190615b4d565b610b009190615b78565b610b1290670de0b6b3a7640000615baa565b905080673782dace9d9000006001600160801b0382161115610b395750673782dace9d9000005b670de0b6b3a76400006001600160801b0382161015610b5d5750670de0b6b3a76400005b84515f90670de0b6b3a764000090610b829062ed4e00906001600160801b0316615b78565b610b8c9190615b4d565b90505f819050806001600160801b031687602001516001600160801b0316141580610bce575062015180876060015163ffffffff1642610bcc9190615bbd565b115b15610e9b5760208701515f906001600160801b031615610cb3575f62ed4e00610c05670de0b6b3a764000063ffffffff8b16615b4d565b610c0f9190615b78565b90505f670de0b6b3a764000082610c2e82673782dace9d900000615b8b565b6001600160801b0316610c419190615b4d565b610c4b9190615b78565b610c5d90670de0b6b3a7640000615baa565b9250829050673782dace9d9000006001600160801b0382161115610c8757673782dace9d90000092505b670de0b6b3a76400006001600160801b0384161015610cac57670de0b6b3a764000092505b5050610cbe565b50670de0b6b3a76400005b87515f90670de0b6b3a764000090610ce2906001600160801b038581169116615b4d565b610cec9190615b78565b89519091505f90670de0b6b3a764000090610d13906001600160801b038981169116615b4d565b610d1d9190615b78565b905081811115610d7b575f610d328383615bbd565b606e805491925082915f90610d519084906001600160801b0316615bd0565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555050610dfd565b80821115610dfd575f610d8e8284615bbd565b606e549091506001600160801b0316811115610db957606e80546001600160801b0319169055610dfb565b606e80548291905f90610dd69084906001600160801b0316615b8b565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b505b610e508b60405180604001604052808d5f0151600f0b81526020018d6040015163ffffffff1681525060405180604001604052808e5f0151600f0b81526020018e6040015163ffffffff168152506139ba565b5050505f88815260666020526040902080546001600160801b03808416600160801b029116178155600101805463ffffffff4216600160201b0267ffffffff00000000199091161790555b5050505050505b33610eac88611ffb565b6001600160a01b031614610ed3576040516359dc379f60e01b815260040160405180910390fd5b5f878152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529103610f4e57604051632254ea3d60e11b815260040160405180910390fd5b5f878260400151610f5f9190615bef565b90505f610f6c4283615b31565b905062ed4e0063ffffffff82161115610f9857604051637616640160e01b815260040160405180910390fd5b5f610fa5845f01516139d3565b90505f610fb28284613a49565b9050886001600160801b0316816001600160801b03161015610fe757604051638199f5f360e01b815260040160405180910390fd5b610ff58c865f015183613b23565b6110448c6040518060400160405280885f0151600f0b8152602001886040015163ffffffff168152506040518060400160405280895f0151600f0b81526020018863ffffffff168152506139ba565b6040518060800160405280865f01516001600160801b03168152602001836001600160801b031681526020018563ffffffff1681526020014263ffffffff1681525060665f8e81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508b336001600160a01b03167f3032be442129e161b4ae1cdee94871a69de2c16ee2007f31fc209a715673455c868460405161119392919063ffffffff9290921682526001600160801b0316602082015260400190565b60405180910390a350505050505050506111ac60015f55565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156111f65750825b90505f826001600160401b031660011480156112115750303b155b90508115801561121f575080155b1561123d5760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561126657845460ff60401b1916600160401b1785555b6001600160a01b038916158061128357506001600160a01b038816155b156112a15760405163d92e233d60e01b815260040160405180910390fd5b6112ab8787613d88565b6112b3613d9a565b6112bb613daa565b6112c433613dba565b6112cc613dcb565b606480546001600160a01b03808c166001600160a01b031992831617909255606f8054928b16929091169190911790555f805260686020527fad6f8124f6081c2622ab3a16acd47af73d52fe87b755c3f897263c58ba3fdbd880544263ffffffff90811663ffffffff194392909216600160201b02919091166001600160401b031990921691909117179055831561139e57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6113b38382613e15565b6113be838383613f36565b505050565b5f811180156113d3575060148111155b6114195760405162461bcd60e51b8152602060048201526012602482015271496e76616c69642062617463682073697a6560701b60448201526064015b60405180910390fd5b5f5b818110801561142957508281105b156111ac575f84848381811061144157611441615af1565b9050602002013590505f6001600160a01b031661145d826138f6565b6001600160a01b0316148061148357505f818152606a602052604090205463ffffffff16155b15611491575060010161141b565b5f818152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b9004909116606082015291036114fd57505060010161141b565b80515f9062ed4e009061151990670de0b6b3a764000090615c0b565b6115239190615c34565b5f848152606a602052604090205490915063ffffffff1660015b8163ffffffff168163ffffffff161161176e575f858152606b6020908152604080832063ffffffff8086168552925282206001810154909291169003611586575060010161153d565b600181015460408601515f9163ffffffff9081169116116115a7575f6115c1565b600182015460408701516115c19163ffffffff1690615b31565b905062ed4e0063ffffffff8216116115d957806115de565b62ed4e005b90505f62ed4e006115ff670de0b6b3a7640000673782dace9d900000615b8b565b61160f9063ffffffff8516615c0b565b6116199190615c34565b61162b90670de0b6b3a7640000615bd0565b83546001600160801b03908116600160801b8983160217855588519181169250670de0b6b3a76400009161166191849116615b4d565b61166b9190615b78565b83546001600160801b0319166001600160801b039190911617835563ffffffff8581169085161015611760575f888152606b60205260408120816116b0876001615bef565b63ffffffff908116825260208083019390935260409182015f2082516080810184528154600f81810b8352600160801b909104900b9481019490945260010154808216928401839052600160201b90041660608301529091501561175e578354602082015161172991600160801b9004600f0b90615c61565b60408281015163ffffffff165f908152606c6020522080546001600160801b0319166001600160801b03929092169190911790555b505b83600101935050505061153d565b508460010194505050505061141b565b5f61178761391d565b61178f613974565b82804211156117b157604051631ab7da6b60e01b815260040160405180910390fd5b856001600160801b03165f036117da5760405163162908e360e11b815260040160405180910390fd5b63ffffffff851615806117f5575062ed4e0063ffffffff8616115b1561181357604051637616640160e01b815260040160405180910390fd5b6001600160a01b03871661183a5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0387165f90815260676020526040902054606460ff909116106118775760405163133cbc4f60e01b815260040160405180910390fd5b5f6118828642615bef565b90505f5f611891898988613fb9565b915091505f60405180604001604052808b600f0b81526020018563ffffffff1681525090506118de5f60405180604001604052805f600f0b81526020015f63ffffffff16815250836139ba565b6064546040516370a0823160e01b81525f916001600160a01b0316906370a082319061190e9030906004016155c2565b602060405180830381865afa158015611929573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061194d9190615c8e565b606454909150611971906001600160a01b031633306001600160801b038f166140ad565b6119846001600160801b038c1682615baa565b6064546040516370a0823160e01b81526001600160a01b03909116906370a08231906119b49030906004016155c2565b602060405180830381865afa1580156119cf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f39190615c8e565b14611a11576040516312171d8360e31b815260040160405180910390fd5b60658054600163ffffffff600160a01b80840482168381019092160263ffffffff60a01b19909316929092179092556001600160a01b038e165f908152606760205260409020805460ff80821690940190931660ff19909316929092179091559650611a7d8c88614118565b604080516080810182526001600160801b03808e168252868116602080840191825263ffffffff808b16858701908152428216606087019081525f8f8152606690945296909220945192518416600160801b0292909316919091178355516001909201805493518216600160201b026001600160401b03199094169290911691909117919091179055611b11878c85613b23565b604080516001600160801b038d16815263ffffffff8716602082015288916001600160a01b038f16915f516020615f6a5f395f51905f52910160405180910390a3505050505050611b6160015f55565b95945050505050565b611b7261391d565b5f611b7c826138f6565b90506001600160a01b038116611ba457604051626f708760e21b815260040160405180910390fd5b6001600160a01b0381163314611bcd576040516359dc379f60e01b815260040160405180910390fd5b5f828152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529103611c4857604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff161015611c795760405163342ad40160e11b815260040160405180910390fd5b8051606e546001600160801b039081169082161115611ca757606e80546001600160801b0319169055611ce9565b606e80548291905f90611cc49084906001600160801b0316615b8b565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b5f84815260666020908152604080832083815560010180546001600160401b031916905580518082018252600f85900b81528582015163ffffffff168184015281518083019092528382529181019290925290611d4990869083906139ba565b5f858152606a60205260409020805463ffffffff19169055606454611d81906001600160a01b0316336001600160801b038516614131565b611d8a85614161565b335f81815260676020908152604091829020805460ff19811660ff9182165f190190911617905590516001600160801b03851681528792917f8903a5b5d08a841e7f68438387f1da20c84dea756379ed37e633ff3854b99b84910160405180910390a350505050611dfa60015f55565b50565b611e05614199565b6001600160a01b038116611e2c5760405163d92e233d60e01b815260040160405180910390fd5b606d80546001600160a01b0319166001600160a01b0392909216919091179055565b6113be83838360405180602001604052805f815250612330565b611e7061391d565b606f54600160a01b900460ff16611ec15760405162461bcd60e51b81526020600482015260156024820152744e6f7420696e20656d657267656e6379206d6f646560581b6044820152606401611410565b33611ecb82611ffb565b6001600160a01b031614611ef2576040516359dc379f60e01b815260040160405180910390fd5b5f818152606660208181526040808420815160808101835281546001600160801b03808216808452600160801b909204168286015260018301805463ffffffff80821696850196909652600160201b81049095166060840152888852959094529490556001600160401b031916909155611f6b83614161565b335f818152606760205260409020805460ff19811660ff9182165f1901909116179055606454611fb0916001600160a01b03909116906001600160801b038416614131565b6040516001600160801b0382168152839033907f4f27eb511b2a4633cfb633ac1c4a99b4c298ca6488b29ec26f3504a5927f67289060200160405180910390a35050611dfa60015f55565b5f61081c8261388b565b5f5f61200f613867565b90506001600160a01b03831661203a575f6040516322718ad960e21b815260040161141091906155c2565b6001600160a01b039092165f908152600390920160205250604090205490565b612062614199565b61206b5f6141cb565b565b612075614199565b6001600160a01b03811661209c5760405163d92e233d60e01b815260040160405180910390fd5b6065546001600160a01b0316156120ef5760405162461bcd60e51b8152602060048201526017602482015276111a5cdd1c9a589d5d1bdc88185b1c9958591e481cd95d604a1b6044820152606401611410565b606580546001600160a01b0319166001600160a01b0392909216919091179055565b5f818152606660209081526040808320815160808101835281546001600160801b038082168352600160801b90910416938101939093526001015463ffffffff808216928401839052600160201b909104811660608401524216106121805750670de0b6b3a764000092915050565b5f4282604001516121919190615b31565b90505f62ed4e006121b0670de0b6b3a764000063ffffffff8516615b4d565b6121ba9190615b78565b90505f670de0b6b3a7640000826121d982673782dace9d900000615b8b565b6001600160801b03166121ec9190615b4d565b6121f69190615b78565b61220890670de0b6b3a7640000615baa565b905080673782dace9d9000006001600160801b03821611156122385750673782dace9d9000009695505050505050565b670de0b6b3a76400006001600160801b03821610156122655750670de0b6b3a76400009695505050505050565b9695505050505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b60605f6122a8613867565b905080600101805461083d90615ab9565b60695463ffffffff9081165f90815260686020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001015480851691830191909152600160201b900490921660608301529061231e818461423b565b9392505050565b6108de338383614371565b61233a8483613e15565b6111ac84848484614414565b61234e61391d565b612356613974565b808042111561237857604051631ab7da6b60e01b815260040160405180910390fd5b600283101561239a5760405163162908e360e11b815260040160405180910390fd5b5f80805b858110156124a357336123c88888848181106123bc576123bc615af1565b90506020020135611ffb565b6001600160a01b0316146123ef576040516359dc379f60e01b815260040160405180910390fd5b5f60665f89898581811061240557612405615af1565b602090810292909201358352508181019290925260409081015f20815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b9004909116606082015291506124789085615bd0565b93508263ffffffff16816040015163ffffffff16111561249a57806040015192505b5060010161239e565b505f6124af4283615b31565b905062ed4e0063ffffffff821611156124db57604051637616640160e01b815260040160405180910390fd5b5f62ed4e006124fb670de0b6b3a76400006001600160801b038716615b4d565b6125059190615b78565b90505f6065601481819054906101000a900463ffffffff1661252690615ca5565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff1690506125553382614118565b5f5b8881101561263f575f8a8a8381811061257257612572615af1565b602090810292909201355f818152606684526040808220815160808101835281546001600160801b038082168352600160801b909104168188015260019091015463ffffffff808216838501908152600160201b90920481166060840152835180850185528351600f0b81529151168188015282518084019093528383529582019290925291945092915061260a90849083906139ba565b5f83815260666020526040812090815560010180546001600160401b031916905561263483614161565b505050600101612557565b50604080518082018252600f87900b815263ffffffff861660208083019190915282518084019093525f808452908301529061267d908390836139ba565b604080516080810182526001600160801b038089168252858116602080840191825263ffffffff808b16858701908152428216606087019081525f8a815260668552888120975195518716600160801b0295909616949094178655516001958601805494518316600160201b026001600160401b031990951691909216179290921790915533808352606790915290839020805460ff8082168f900390940190931660ff199093169290921790915590518391905f516020615f6a5f395f51905f5290612767908a908a906001600160801b0392909216825263ffffffff16602082015260400190565b60405180910390a3505050505050506113be60015f55565b61278761391d565b61278f613974565b81804211156127b157604051631ab7da6b60e01b815260040160405180910390fd5b5f85815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b900490921660608301528691901580159061282e5750806040015163ffffffff164263ffffffff16105b15612c4b575f4282604001516128449190615b31565b90505f62ed4e00612863670de0b6b3a764000063ffffffff8516615b4d565b61286d9190615b78565b90505f670de0b6b3a76400008261288c82673782dace9d900000615b8b565b6001600160801b031661289f9190615b4d565b6128a99190615b78565b6128bb90670de0b6b3a7640000615baa565b905080673782dace9d9000006001600160801b03821611156128e25750673782dace9d9000005b670de0b6b3a76400006001600160801b03821610156129065750670de0b6b3a76400005b84515f90670de0b6b3a76400009061292b9062ed4e00906001600160801b0316615b78565b6129359190615b4d565b90505f819050806001600160801b031687602001516001600160801b0316141580612977575062015180876060015163ffffffff16426129759190615bbd565b115b15612c445760208701515f906001600160801b031615612a5c575f62ed4e006129ae670de0b6b3a764000063ffffffff8b16615b4d565b6129b89190615b78565b90505f670de0b6b3a7640000826129d782673782dace9d900000615b8b565b6001600160801b03166129ea9190615b4d565b6129f49190615b78565b612a0690670de0b6b3a7640000615baa565b9250829050673782dace9d9000006001600160801b0382161115612a3057673782dace9d90000092505b670de0b6b3a76400006001600160801b0384161015612a5557670de0b6b3a764000092505b5050612a67565b50670de0b6b3a76400005b87515f90670de0b6b3a764000090612a8b906001600160801b038581169116615b4d565b612a959190615b78565b89519091505f90670de0b6b3a764000090612abc906001600160801b038981169116615b4d565b612ac69190615b78565b905081811115612b24575f612adb8383615bbd565b606e805491925082915f90612afa9084906001600160801b0316615bd0565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555050612ba6565b80821115612ba6575f612b378284615bbd565b606e549091506001600160801b0316811115612b6257606e80546001600160801b0319169055612ba4565b606e80548291905f90612b7f9084906001600160801b0316615b8b565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b505b612bf98b60405180604001604052808d5f0151600f0b81526020018d6040015163ffffffff1681525060405180604001604052808e5f0151600f0b81526020018e6040015163ffffffff168152506139ba565b5050505f88815260666020526040902080546001600160801b03808416600160801b029116178155600101805463ffffffff4216600160201b0267ffffffff00000000199091161790555b5050505050505b32612c5588611ffb565b6001600160a01b031614612c945733612c6d88611ffb565b6001600160a01b031614612c94576040516359dc379f60e01b815260040160405180910390fd5b856001600160801b03165f03612cbd5760405163162908e360e11b815260040160405180910390fd5b5f878152606660205260408120805490916001600160801b039091169003612cf857604051632254ea3d60e11b815260040160405180910390fd5b600181015463ffffffff9081164290911610612d27576040516307b7d7dd60e51b815260040160405180910390fd5b6064546040516370a0823160e01b81525f916001600160a01b0316906370a0823190612d579030906004016155c2565b602060405180830381865afa158015612d72573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d969190615c8e565b606454909150612dba906001600160a01b031633306001600160801b038c166140ad565b612dcd6001600160801b03891682615baa565b6064546040516370a0823160e01b81526001600160a01b03909116906370a0823190612dfd9030906004016155c2565b602060405180830381865afa158015612e18573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e3c9190615c8e565b14612e5a576040516312171d8360e31b815260040160405180910390fd5b612e6589898861442c565b50505050506111ac60015f55565b612e7b614199565b606f805460ff60a01b1916600160a01b179055612e96613dcb565b606f546040517fc0a1c7e9f05b4d536e1ff8606bae9b847cdb43ef4a9b2d7a503a88cee08dccdb91612ed3916001600160a01b03909116906155c2565b60405180910390a1565b60605f612ee9836138f6565b6001600160a01b031603612f0f57604051626f708760e21b815260040160405180910390fd5b606d546001600160a01b0316612f38576040516338a69c8d60e21b815260040160405180910390fd5b606d54604051602481018490525f9182916001600160a01b039091169060440160408051601f198184030181529181526020820180516001600160e01b031663c87b56dd60e01b17905251612f8d9190615cc9565b5f60405180830381855afa9150503d805f8114612fc5576040519150601f19603f3d011682016040523d82523d5f602084013e612fca565b606091505b5091509150816130145760405162461bcd60e51b8152602060048201526015602482015274105c9d081c1c9bde1e4818d85b1b0819985a5b1959605a1b6044820152606401611410565b808060200190518101906130289190615cdf565b949350505050565b5f63ffffffff8216158061304c575062ed4e0063ffffffff8316115b1561306a57604051637616640160e01b815260040160405180910390fd5b826001600160801b03165f036130935760405163162908e360e11b815260040160405180910390fd5b5f670de0b6b3a76400006130b362ed4e006001600160801b038716615b78565b6130bd9190615b4d565b9050805f036130d757670de0b6b3a764000091505061081c565b5f62ed4e006130f4670de0b6b3a764000063ffffffff8716615b4d565b6130fe9190615b78565b90505f670de0b6b3a764000061311c81673782dace9d900000615b8b565b61312f906001600160801b031684615b4d565b6131399190615b78565b61314b90670de0b6b3a7640000615baa565b9050673782dace9d900000811161317f57670de0b6b3a764000081106131715780612265565b670de0b6b3a7640000612265565b673782dace9d9000009695505050505050565b5f828152606a602052604081205463ffffffff168082036131b6575f91505061081c565b5f84815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b90049092166060830152158061322f5750806040015163ffffffff168463ffffffff1610155b1561323e575f9250505061081c565b815b60018163ffffffff16106133ea575f868152606b6020908152604080832063ffffffff80861685529083529281902081516080810183528154600f81810b8352600160801b909104900b9381019390935260010154808416918301829052600160201b90048316606083015290918716106133d75760408301515f9062ed4e0090670de0b6b3a7640000906132d6908a90615b31565b63ffffffff166132e69190615b4d565b6132f09190615b78565b90505f670de0b6b3a764000061330e81673782dace9d900000615b8b565b613321906001600160801b031684615b4d565b61332b9190615b78565b61333d90670de0b6b3a7640000615baa565b9050673782dace9d900000811161337157670de0b6b3a76400008110613363578061337b565b670de0b6b3a764000061337b565b673782dace9d9000005b83519091505f90670de0b6b3a7640000906133a09084906001600160801b0316615b4d565b6133aa9190615b78565b90506001600160801b0381116133c057806133c9565b6001600160801b035b97505050505050505061081c565b50806133e281615d53565b915050613240565b505f95945050505050565b606d545f90819063ffffffff600160a01b9091048116908416116134195782613433565b606d5461343390600160a01b900463ffffffff1684615b31565b90506130288482613030565b5f61344861391d565b613450613974565b828042111561347257604051631ab7da6b60e01b815260040160405180910390fd5b856001600160801b03165f0361349b5760405163162908e360e11b815260040160405180910390fd5b63ffffffff851615806134b6575062ed4e0063ffffffff8616115b156134d457604051637616640160e01b815260040160405180910390fd5b335f90815260676020526040902054606460ff909116106135085760405163133cbc4f60e01b815260040160405180910390fd5b5f6135138642615bef565b90505f5f613522898988613fb9565b915091505f60405180604001604052808b600f0b81526020018563ffffffff16815250905061356f5f60405180604001604052805f600f0b81526020015f63ffffffff16815250836139ba565b6064546040516370a0823160e01b81525f916001600160a01b0316906370a082319061359f9030906004016155c2565b602060405180830381865afa1580156135ba573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135de9190615c8e565b606454909150613602906001600160a01b031633306001600160801b038f166140ad565b6136156001600160801b038c1682615baa565b6064546040516370a0823160e01b81526001600160a01b03909116906370a08231906136459030906004016155c2565b602060405180830381865afa158015613660573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136849190615c8e565b146136a2576040516312171d8360e31b815260040160405180910390fd5b60658054600163ffffffff600160a01b80840482168381019092160263ffffffff60a01b1990931692909217909255335f818152606760205260409020805460ff80821690950190941660ff199094169390931790925597506137059088614118565b604080516080810182526001600160801b03808e168252868116602080840191825263ffffffff808b16858701908152428216606087019081525f8f8152606690945296909220945192518416600160801b0292909316919091178355516001909201805493518216600160201b026001600160401b03199094169290911691909117919091179055613799878c85613b23565b604080516001600160801b038d16815263ffffffff87166020820152889133915f516020615f6a5f395f51905f52910160405180910390a350505050505061302860015f55565b5f5f6137ea613867565b6001600160a01b039485165f90815260059190910160209081526040808320959096168252939093525050205460ff1690565b613825614199565b6001600160a01b03811661384e575f604051631e4fbdf760e01b815260040161141091906155c2565b611dfa816141cb565b61385f614199565b61206b6145ff565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930090565b5f5f613896836138f6565b90506001600160a01b03811661081c57604051637e27328960e01b815260048101849052602401611410565b5f5f6138cc613867565b5f938452600401602052505060409020546001600160a01b031690565b6113be8383836001614638565b5f5f613900613867565b5f938452600201602052505060409020546001600160a01b031690565b60025f540361396e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611410565b60025f55565b60325460ff161561206b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401611410565b6139c261473f565b82156113be576113be838383614900565b5f806139eb62ed4e006001600160801b038516615b78565b90506139ff670de0b6b3a764000082615b4d565b90506001600160801b0381111561081c5760405162461bcd60e51b815260206004820152600e60248201526d0a6d8dee0ca40e8dede40d0d2ced60931b6044820152606401611410565b5f826001600160801b03165f03613a695750670de0b6b3a764000061081c565b5f62ed4e00613a86670de0b6b3a764000063ffffffff8616615b4d565b613a909190615b78565b90505f670de0b6b3a7640000613aae81673782dace9d900000615b8b565b613ac1906001600160801b031684615b4d565b613acb9190615b78565b613add90670de0b6b3a7640000615baa565b9050673782dace9d900000811115613b0157673782dace9d9000009250505061081c565b670de0b6b3a764000081101561302857670de0b6b3a76400009250505061081c565b5f838152606660209081526040808320815160808101835281546001600160801b038082168352600160801b9091041693810184905260019091015463ffffffff80821693830193909352600160201b900490911660608201529190613b9157670de0b6b3a7640000613bd1565b428260400151613ba19190615b31565b63ffffffff1682602001516001600160801b0316613bbf9190615b4d565b613bd190670de0b6b3a7640000615baa565b9050673782dace9d9000006001600160801b0382161115613bf75750673782dace9d9000005b670de0b6b3a76400006001600160801b0382161015613c1b5750670de0b6b3a76400005b5f670de0b6b3a7640000613c3b6001600160801b03848116908816615b4d565b613c459190615b78565b90505f670de0b6b3a7640000613c676001600160801b03878116908916615b4d565b613c719190615b78565b905081811115613cf7575f613c868383615bbd565b90506001600160801b03811115613cb057604051630fc12e3560e11b815260040160405180910390fd5b606e80548291905f90613ccd9084906001600160801b0316615bd0565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555050613d79565b80821115613d79575f613d0a8284615bbd565b606e549091506001600160801b0316811115613d3557606e80546001600160801b0319169055613d77565b606e80548291905f90613d529084906001600160801b0316615b8b565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b505b50505050505050565b60015f55565b613d906149f9565b6108de8282614a42565b613da26149f9565b61206b614a6f565b613db26149f9565b61206b614a77565b613dc26149f9565b611dfa81614a8b565b613dd3613974565b6032805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613e083390565b604051612ed391906155c2565b6001600160a01b03821615801590613e3757506065546001600160a01b031615155b8015613e5457505f613e48826138f6565b6001600160a01b031614155b156108de5760655460405163135bb63160e21b8152600481018390525f916001600160a01b031690634d6ed8c490602401602060405180830381865afa158015613ea0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613ec49190615c8e565b11156108de5760655460405163379607f560e01b8152600481018390526001600160a01b039091169063379607f5906024016020604051808303815f875af1158015613f12573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113be9190615c8e565b6001600160a01b038216613f5f575f604051633250574960e11b815260040161141091906155c2565b5f613f6b838333614a93565b9050836001600160a01b0316816001600160a01b0316146111ac576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401611410565b5f8080613fd262ed4e006001600160801b038816615b78565b9050613fe6670de0b6b3a764000082615b4d565b90506001600160801b038111156140305760405162461bcd60e51b815260206004820152600e60248201526d536c6f7065206f766572666c6f7760901b6044820152606401611410565b80925061403d8386613a49565b9150673782dace9d9000006001600160801b038316111561407157604051638f651fb760e01b815260040160405180910390fd5b836001600160801b0316826001600160801b031610156140a457604051638199f5f360e01b815260040160405180910390fd5b50935093915050565b6040516001600160a01b03808516602483015283166044820152606481018290526111ac9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614b92565b6108de828260405180602001604052805f815250614c65565b6040516001600160a01b0383166024820152604481018290526113be90849063a9059cbb60e01b906064016140e1565b5f61416d5f835f614a93565b90506001600160a01b0381166108de57604051637e27328960e01b815260048101839052602401611410565b336141a261226f565b6001600160a01b03161461206b573360405163118cdaa760e01b815260040161141091906155c2565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f5f62093a808085604001516142519190615d71565b61425b9190615d98565b90505f5b60ff81101561434c5761427562093a8083615bef565b91508363ffffffff168263ffffffff1611156142c957604085015161429a9085615b31565b63ffffffff1685602001516142af9190615db7565b855186906142be908390615c61565b600f0b90525061434c565b60408501516142d89083615b31565b63ffffffff1685602001516142ed9190615db7565b855186906142fc908390615c61565b600f90810b90915263ffffffff84165f908152606c602090815260409091205490880180519190920b9250614332908390615dd6565b600f0b90525063ffffffff8216604086015260010161425f565b505f845f0151600f0b121561435f575f84525b505090516001600160801b0316919050565b5f61437a613867565b90506001600160a01b0383166143a55782604051630b61174360e31b815260040161141091906155c2565b6001600160a01b038481165f818152600584016020908152604080832094881680845294825291829020805460ff191687151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b61441f8484846113a9565b6111ac3385858585614c78565b5f838152606660205260408120805490916001600160801b03909116906144538583615bd0565b600184015490915063ffffffff165f61446c4283615b31565b90505f614478846139d3565b90505f6144858284613a49565b90505f6144918b612111565b9050806001600160801b0316826001600160801b0316116144b257806144b4565b815b91506144ca6103e8670de0b6b3a7640000615c34565b6001600160801b03168a6001600160801b03161180156144fb5750886001600160801b0316826001600160801b0316105b1561451957604051638199f5f360e01b815260040160405180910390fd5b61455e8b60405180604001604052808a600f0b81526020018863ffffffff1681525060405180604001604052808a600f0b81526020018963ffffffff168152506139ba565b6001600160801b03838116600160801b0290871617885560018801805463ffffffff4216600160201b0267ffffffff00000000199091161790556145a38b8b84613b23565b604080516001600160801b038c81168252888116602083015284168183015290518c9133917f1381e2f7d0d4b71a58d34dc3db2051dd52769766e65eabf380c9b4ea93f0890b9181900360600190a35050505050505050505050565b614607614d8e565b6032805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33613e08565b5f614641613867565b9050818061465757506001600160a01b03831615155b1561470f575f6146668561388b565b90506001600160a01b038416158015906146925750836001600160a01b0316816001600160a01b031614155b80156146a557506146a381856137e0565b155b156146c5578360405163a9fbf51f60e01b815260040161141091906155c2565b821561470d5784866001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5f93845260040160205250506040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60695463ffffffff16614750615515565b63ffffffff8216156147c95760685f61476a600185615b31565b63ffffffff908116825260208083019390935260409182015f2082516080810184528154600f81810b8352600160801b909104900b948101949094526001015480821692840192909252600160201b90910416606082015290506147f6565b50604080516080810182525f808252602082015263ffffffff428116928201929092524390911660608201525b60408101515f63ffffffff8083164290911611156148575760408301516148239063ffffffff1642615bbd565b60608401516148389063ffffffff1643615bbd565b61484a90670de0b6b3a7640000615b4d565b6148549190615b78565b90505b61486383838387614dd7565b9250614870846001615bef565b6069805463ffffffff92831663ffffffff199091161790558481165f9081526068602090815260408083208751928801516001600160801b03908116600160801b0290841617815590870151600191909101805460608901518616600160201b026001600160401b0319909116929095169190911793909317909255600f9190910b12156111ac5750505f905250565b614908615515565b614910615515565b61491a8483614fe0565b506149258382614fe0565b5061493a84848460200151846020015161512f565b5f858152606a60205260408120546149599063ffffffff166001615bef565b5f878152606a60209081526040808320805463ffffffff95861663ffffffff199091168117909155428516878301908152438616606089019081529b8552606b84528285209185529083529220855195909101516001600160801b03908116600160801b02951694909417845551600193909301805497518216600160201b026001600160401b0319909816939091169290921795909517905550505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661206b57604051631afcd79f60e31b815260040160405180910390fd5b614a4a6149f9565b5f614a53613867565b905080614a608482615e47565b50600181016111ac8382615e47565b613d826149f9565b614a7f6149f9565b6032805460ff19169055565b6138256149f9565b5f5f614a9d613867565b90505f614aa9856138f6565b90506001600160a01b03841615614ac557614ac581858761526a565b6001600160a01b03811615614b0157614ae05f865f5f614638565b6001600160a01b0381165f908152600383016020526040902080545f190190555b6001600160a01b03861615614b31576001600160a01b0386165f9081526003830160205260409020805460010190555b5f85815260028301602052604080822080546001600160a01b0319166001600160a01b038a811691821790925591518893918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a495945050505050565b5f614be6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166152ce9092919063ffffffff16565b905080515f1480614c06575080806020019051810190614c069190615f01565b6113be5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611410565b614c6f83836152dc565b6113be335f8585855b6001600160a01b0383163b15614d8757604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290614cba908890889087908790600401615f1c565b6020604051808303815f875af1925050508015614cf4575060408051601f3d908101601f19168201909252614cf191810190615f4e565b60015b614d52573d808015614d21576040519150601f19603f3d011682016040523d82523d5f602084013e614d26565b606091505b5080515f03614d4a5783604051633250574960e11b815260040161141091906155c2565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14614d855783604051633250574960e11b815260040161141091906155c2565b505b5050505050565b60325460ff1661206b5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401611410565b614ddf615515565b5f62093a80614dee8187615d71565b614df89190615d98565b9050425f5b60ff811015614fd457614e1362093a8084615bef565b92508163ffffffff168363ffffffff161115614e7657614e338783615b31565b63ffffffff168860200151614e489190615db7565b88518990614e57908390615c61565b600f0b90525063ffffffff80831660408a015243166060890152614fd4565b614e808784615b31565b63ffffffff168860200151614e959190615db7565b88518990614ea4908390615c61565b600f90810b90915263ffffffff85165f908152606c6020908152604090912054908b0180519190920b9250614eda908390615dd6565b600f0b90525063ffffffff831660408901819052670de0b6b3a764000090614f029085615b31565b614f1b9063ffffffff166001600160801b038916615b4d565b614f259190615b78565b886060015163ffffffff16614f3a9190615baa565b63ffffffff1660608901528760685f83614f55896001615bef565b614f5f9190615bef565b63ffffffff908116825260208083019390935260409182015f208451938501516001600160801b03908116600160801b02941693909317835590830151600192830180546060909501518316600160201b026001600160401b0319909516919092161792909217909155929650869201614dfd565b50959695505050505050565b5f4263ffffffff16836020015163ffffffff1611158061500257508251600f0b155b1561500e57505f61081c565b5f42846020015161501f9190615b31565b63ffffffff16905062ed4e008111615037578061503c565b62ed4e005b90505f62ed4e0061505d670de0b6b3a7640000673782dace9d900000615b8b565b615070906001600160801b031684615b4d565b61507a9190615b78565b61508c90670de0b6b3a7640000615baa565b9050673782dace9d90000081116150c057670de0b6b3a764000081106150b257806150ca565b670de0b6b3a76400006150ca565b673782dace9d9000005b85519091506001600160801b0316670de0b6b3a76400006150eb8383615b4d565b6150f59190615b78565b600f0b855262ed4e00615110670de0b6b3a764000083615b4d565b61511a9190615b78565b600f0b60208601525060019250505092915050565b4263ffffffff16846020015163ffffffff1611156151d05760208085015163ffffffff165f908152606c9091526040902054600f0b61516e8382615dd6565b9050846020015163ffffffff16846020015163ffffffff1603615198576151958282615c61565b90505b60208581015163ffffffff165f908152606c9091526040902080546001600160801b0319166001600160801b03929092169190911790555b4263ffffffff16836020015163ffffffff1611156111ac57836020015163ffffffff16836020015163ffffffff1611156111ac5760208084015163ffffffff165f908152606c9091526040902054600f0b61522b8282615c61565b60208086015163ffffffff165f908152606c9091526040902080546001600160801b039092166001600160801b03199092169190911790555050505050565b61527583838361533d565b6113be576001600160a01b0383166152a357604051637e27328960e01b815260048101829052602401611410565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401611410565b606061302884845f856153a1565b6001600160a01b038216615305575f604051633250574960e11b815260040161141091906155c2565b5f61531183835f614a93565b90506001600160a01b038116156113be575f6040516339e3563760e11b815260040161141091906155c2565b5f6001600160a01b038316158015906130285750826001600160a01b0316846001600160a01b03161480615376575061537684846137e0565b806130285750826001600160a01b031661538f836138c2565b6001600160a01b031614949350505050565b6060824710156154025760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401611410565b5f5f866001600160a01b0316858760405161541d9190615cc9565b5f6040518083038185875af1925050503d805f8114615457576040519150601f19603f3d011682016040523d82523d5f602084013e61545c565b606091505b509150915061546d87838387615478565b979650505050505050565b606083156154e65782515f036154df576001600160a01b0385163b6154df5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611410565b5081613028565b61302883838151156154fb5781518083602001fd5b8060405162461bcd60e51b81526004016114109190615599565b604080516080810182525f80825260208201819052918101829052606081019190915290565b6001600160e01b031981168114611dfa575f5ffd5b5f60208284031215615560575f5ffd5b813561231e8161553b565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61231e602083018461556b565b5f602082840312156155bb575f5ffd5b5035919050565b6001600160a01b0391909116815260200190565b80356001600160a01b03811681146155ec575f5ffd5b919050565b5f5f60408385031215615602575f5ffd5b61560b836155d6565b946020939093013593505050565b5f60208284031215615629575f5ffd5b61231e826155d6565b602080825282518282018190525f918401906040840190835b8181101561566957835183526020938401939092019160010161564b565b509095945050505050565b803563ffffffff811681146155ec575f5ffd5b5f5f60408385031215615698575f5ffd5b823591506156a860208401615674565b90509250929050565b80356001600160801b03811681146155ec575f5ffd5b5f5f5f5f608085870312156156da575f5ffd5b843593506156ea60208601615674565b9250604085013591506156ff606086016156b1565b905092959194509250565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156157465761574661570a565b604052919050565b5f6001600160401b038211156157665761576661570a565b50601f01601f191660200190565b5f6157866157818461574e565b61571e565b9050828152838383011115615799575f5ffd5b828260208301375f602084830101529392505050565b5f82601f8301126157be575f5ffd5b61231e83833560208501615774565b5f5f5f5f608085870312156157e0575f5ffd5b6157e9856155d6565b93506157f7602086016155d6565b925060408501356001600160401b03811115615811575f5ffd5b61581d878288016157af565b92505060608501356001600160401b03811115615838575f5ffd5b615844878288016157af565b91505092959194509250565b5f5f5f60608486031215615862575f5ffd5b61586b846155d6565b9250615879602085016155d6565b929592945050506040919091013590565b5f5f5f6040848603121561589c575f5ffd5b83356001600160401b038111156158b1575f5ffd5b8401601f810186136158c1575f5ffd5b80356001600160401b038111156158d6575f5ffd5b8660208260051b84010111156158ea575f5ffd5b6020918201979096509401359392505050565b5f5f5f5f5f60a08688031215615911575f5ffd5b61591a866155d6565b9450615928602087016156b1565b935061593660408701615674565b92506060860135915061594b608087016156b1565b90509295509295909350565b5f60208284031215615967575f5ffd5b61231e82615674565b8015158114611dfa575f5ffd5b5f5f6040838503121561598e575f5ffd5b615997836155d6565b915060208301356159a781615970565b809150509250929050565b5f5f5f5f608085870312156159c5575f5ffd5b6159ce856155d6565b93506159dc602086016155d6565b92506040850135915060608501356001600160401b038111156159fd575f5ffd5b8501601f81018713615a0d575f5ffd5b61584487823560208401615774565b5f5f5f5f60808587031215615a2f575f5ffd5b843593506156ea602086016156b1565b5f5f60408385031215615a50575f5ffd5b615a59836156b1565b91506156a860208401615674565b5f5f5f5f60808587031215615a7a575f5ffd5b615a83856156b1565b93506156ea60208601615674565b5f5f60408385031215615aa2575f5ffd5b615aab836155d6565b91506156a8602084016155d6565b600181811c90821680615acd57607f821691505b602082108103615aeb57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201615b2a57615b2a615b05565b5060010190565b63ffffffff828116828216039081111561081c5761081c615b05565b808202811582820484141761081c5761081c615b05565b634e487b7160e01b5f52601260045260245ffd5b5f82615b8657615b86615b64565b500490565b6001600160801b03828116828216039081111561081c5761081c615b05565b8082018082111561081c5761081c615b05565b8181038181111561081c5761081c615b05565b6001600160801b03818116838216019081111561081c5761081c615b05565b63ffffffff818116838216019081111561081c5761081c615b05565b6001600160801b038181168382160290811690818114615c2d57615c2d615b05565b5092915050565b5f6001600160801b03831680615c4c57615c4c615b64565b806001600160801b0384160491505092915050565b600f82810b9082900b0360016001607f1b0319811260016001607f1b038213171561081c5761081c615b05565b5f60208284031215615c9e575f5ffd5b5051919050565b5f63ffffffff821663ffffffff8103615cc057615cc0615b05565b60010192915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615cef575f5ffd5b81516001600160401b03811115615d04575f5ffd5b8201601f81018413615d14575f5ffd5b8051615d226157818261574e565b818152856020838501011115615d36575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f63ffffffff821680615d6857615d68615b05565b5f190192915050565b5f63ffffffff831680615d8657615d86615b64565b8063ffffffff84160491505092915050565b63ffffffff8181168382160290811690818114615c2d57615c2d615b05565b5f82600f0b82600f0b0280600f0b9150808214615c2d57615c2d615b05565b600f81810b9083900b0160016001607f1b03811360016001607f1b03198212171561081c5761081c615b05565b601f8211156113be57805f5260205f20601f840160051c81016020851015615e285750805b601f840160051c820191505b81811015614d87575f8155600101615e34565b81516001600160401b03811115615e6057615e6061570a565b615e7481615e6e8454615ab9565b84615e03565b6020601f821160018114615ea6575f8315615e8f5750848201515b5f19600385901b1c1916600184901b178455614d87565b5f84815260208120601f198516915b82811015615ed55787850151825560209485019460019092019101615eb5565b5084821015615ef257868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215615f11575f5ffd5b815161231e81615970565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f906122659083018461556b565b5f60208284031215615f5e575f5ffd5b815161231e8161553b56fedbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f8597828934954a26469706673582212206c7cfd799d498e0dfe91275b4c271b021d906df60b72e04d91b2a212e82147b964736f6c634300081b0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610297575f3560e01c806375619ab511610161578063bcc00225116100ca578063df0c78ef11610084578063df0c78ef14610758578063df2151571461076b578063e58f59471461077e578063e985e9c5146107a3578063f2fde38b146107b6578063f7b188a5146107c9575f5ffd5b8063bcc00225146106e2578063beb8310914610704578063c5b1c7d014610717578063c87b56dd1461071f578063d89dd26914610732578063ddacc94a14610745575f5ffd5b806395d89b411161011b57806395d89b411461065157806397612d4b146106595780639b7d02ad1461066c578063a22cb465146106a9578063b88d4fde146106bc578063bbe33ea5146106cf575f5ffd5b806375619ab51461053457806389f839c6146105475780638b25e8c1146105ca5780638da5cb5b146105dd5780638ff42490146105e5578063900cf0cf1461062c575f5ffd5b8063268dc199116102035780635594a045116101bd5780635594a045146104b3578063586c2600146104c65780635c975abb146104fb5780636352211e1461050657806370a0823114610519578063715018a61461052c575f5ffd5b8063268dc199146104215780632a90752d146104465780632e1a7d4d146104675780632e720f7d1461047a57806342842e0e1461048d5780635312ea8e146104a0575f5ffd5b80631d237a49116102545780631d237a491461033e5780631f5ab022146103c35780632016a0d2146103d657806320a194b8146103e957806323b872dd146103fb57806325f521e41461040e575f5ffd5b806301ffc9a71461029b57806306fdde03146102c3578063081812fc146102d8578063095ea7b3146102f85780630f45cc811461030d57806313de148b1461031e575b5f5ffd5b6102ae6102a9366004615550565b6107d1565b60405190151581526020015b60405180910390f35b6102cb610822565b6040516102ba9190615599565b6102eb6102e63660046155ab565b6108bf565b6040516102ba91906155c2565b61030b6103063660046155f1565b6108d3565b005b6064546001600160a01b03166102eb565b61033161032c366004615619565b6108e2565b6040516102ba9190615632565b61039061034c366004615687565b606b60209081525f928352604080842090915290825290208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60408051600f95860b81529390940b602084015263ffffffff9182169383019390935290911660608201526080016102ba565b61030b6103d13660046156c7565b6109d6565b61030b6103e43660046157cd565b6111b2565b606f54600160a01b900460ff166102ae565b61030b610409366004615850565b6113a9565b61030b61041c36600461588a565b6113c3565b606e546001600160801b03165b6040516001600160801b0390911681526020016102ba565b6104596104543660046158fd565b61177e565b6040519081526020016102ba565b61030b6104753660046155ab565b611b6a565b61030b610488366004615619565b611dfd565b61030b61049b366004615850565b611e4e565b61030b6104ae3660046155ab565b611e68565b606d546102eb906001600160a01b031681565b6104e86104d4366004615957565b606c6020525f9081526040902054600f0b81565b604051600f9190910b81526020016102ba565b60325460ff166102ae565b6102eb6105143660046155ab565b611ffb565b610459610527366004615619565b612005565b61030b61205a565b61030b610542366004615619565b61206d565b6105936105553660046155ab565b60666020525f9081526040902080546001909101546001600160801b0380831692600160801b9004169063ffffffff80821691600160201b90041684565b604080516001600160801b03958616815294909316602085015263ffffffff918216928401929092521660608201526080016102ba565b61042e6105d83660046155ab565b612111565b6102eb61226f565b6103906105f3366004615957565b60686020525f908152604090208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60695461063c9063ffffffff1681565b60405163ffffffff90911681526020016102ba565b6102cb61229d565b61042e610667366004615957565b6122b9565b61069761067a366004615619565b6001600160a01b03165f9081526067602052604090205460ff1690565b60405160ff90911681526020016102ba565b61030b6106b736600461597d565b612325565b61030b6106ca3660046159b2565b612330565b61030b6106dd36600461588a565b612346565b6106976106f0366004615619565b60676020525f908152604090205460ff1681565b61030b610712366004615a1c565b61277f565b61030b612e73565b6102cb61072d3660046155ab565b612edd565b61042e610740366004615a3f565b613030565b61042e610753366004615687565b613192565b61042e610766366004615a3f565b6133f5565b610459610779366004615a67565b61343f565b61063c61078c3660046155ab565b606a6020525f908152604090205463ffffffff1681565b6102ae6107b1366004615a91565b6137e0565b61030b6107c4366004615619565b61381d565b61030b613857565b5f6001600160e01b031982166380ac58cd60e01b148061080157506001600160e01b03198216635b5e139f60e01b145b8061081c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60605f61082d613867565b9050805f01805461083d90615ab9565b80601f016020809104026020016040519081016040528092919081815260200182805461086990615ab9565b80156108b45780601f1061088b576101008083540402835291602001916108b4565b820191905f5260205f20905b81548152906001019060200180831161089757829003601f168201915b505050505091505090565b5f6108c98261388b565b5061081c826138c2565b6108de8282336138e9565b5050565b6001600160a01b0381165f9081526067602052604090205460609060ff16806001600160401b038111156109185761091861570a565b604051908082528060200260200182016040528015610941578160200160208202803683370190505b5091508060ff165f036109545750919050565b5f805b606554600160a01b900463ffffffff168110156109ce57846001600160a01b0316610981826138f6565b6001600160a01b0316036109c657808483815181106109a2576109a2615af1565b6020908102919091010152816109b781615b19565b9250508260ff168210156109ce575b600101610957565b505050919050565b6109de61391d565b6109e6613974565b8180421115610a0857604051631ab7da6b60e01b815260040160405180910390fd5b5f85815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b9004909216606083015286919015801590610a855750806040015163ffffffff164263ffffffff16105b15610ea2575f428260400151610a9b9190615b31565b90505f62ed4e00610aba670de0b6b3a764000063ffffffff8516615b4d565b610ac49190615b78565b90505f670de0b6b3a764000082610ae382673782dace9d900000615b8b565b6001600160801b0316610af69190615b4d565b610b009190615b78565b610b1290670de0b6b3a7640000615baa565b905080673782dace9d9000006001600160801b0382161115610b395750673782dace9d9000005b670de0b6b3a76400006001600160801b0382161015610b5d5750670de0b6b3a76400005b84515f90670de0b6b3a764000090610b829062ed4e00906001600160801b0316615b78565b610b8c9190615b4d565b90505f819050806001600160801b031687602001516001600160801b0316141580610bce575062015180876060015163ffffffff1642610bcc9190615bbd565b115b15610e9b5760208701515f906001600160801b031615610cb3575f62ed4e00610c05670de0b6b3a764000063ffffffff8b16615b4d565b610c0f9190615b78565b90505f670de0b6b3a764000082610c2e82673782dace9d900000615b8b565b6001600160801b0316610c419190615b4d565b610c4b9190615b78565b610c5d90670de0b6b3a7640000615baa565b9250829050673782dace9d9000006001600160801b0382161115610c8757673782dace9d90000092505b670de0b6b3a76400006001600160801b0384161015610cac57670de0b6b3a764000092505b5050610cbe565b50670de0b6b3a76400005b87515f90670de0b6b3a764000090610ce2906001600160801b038581169116615b4d565b610cec9190615b78565b89519091505f90670de0b6b3a764000090610d13906001600160801b038981169116615b4d565b610d1d9190615b78565b905081811115610d7b575f610d328383615bbd565b606e805491925082915f90610d519084906001600160801b0316615bd0565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555050610dfd565b80821115610dfd575f610d8e8284615bbd565b606e549091506001600160801b0316811115610db957606e80546001600160801b0319169055610dfb565b606e80548291905f90610dd69084906001600160801b0316615b8b565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b505b610e508b60405180604001604052808d5f0151600f0b81526020018d6040015163ffffffff1681525060405180604001604052808e5f0151600f0b81526020018e6040015163ffffffff168152506139ba565b5050505f88815260666020526040902080546001600160801b03808416600160801b029116178155600101805463ffffffff4216600160201b0267ffffffff00000000199091161790555b5050505050505b33610eac88611ffb565b6001600160a01b031614610ed3576040516359dc379f60e01b815260040160405180910390fd5b5f878152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529103610f4e57604051632254ea3d60e11b815260040160405180910390fd5b5f878260400151610f5f9190615bef565b90505f610f6c4283615b31565b905062ed4e0063ffffffff82161115610f9857604051637616640160e01b815260040160405180910390fd5b5f610fa5845f01516139d3565b90505f610fb28284613a49565b9050886001600160801b0316816001600160801b03161015610fe757604051638199f5f360e01b815260040160405180910390fd5b610ff58c865f015183613b23565b6110448c6040518060400160405280885f0151600f0b8152602001886040015163ffffffff168152506040518060400160405280895f0151600f0b81526020018863ffffffff168152506139ba565b6040518060800160405280865f01516001600160801b03168152602001836001600160801b031681526020018563ffffffff1681526020014263ffffffff1681525060665f8e81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508b336001600160a01b03167f3032be442129e161b4ae1cdee94871a69de2c16ee2007f31fc209a715673455c868460405161119392919063ffffffff9290921682526001600160801b0316602082015260400190565b60405180910390a350505050505050506111ac60015f55565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156111f65750825b90505f826001600160401b031660011480156112115750303b155b90508115801561121f575080155b1561123d5760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561126657845460ff60401b1916600160401b1785555b6001600160a01b038916158061128357506001600160a01b038816155b156112a15760405163d92e233d60e01b815260040160405180910390fd5b6112ab8787613d88565b6112b3613d9a565b6112bb613daa565b6112c433613dba565b6112cc613dcb565b606480546001600160a01b03808c166001600160a01b031992831617909255606f8054928b16929091169190911790555f805260686020527fad6f8124f6081c2622ab3a16acd47af73d52fe87b755c3f897263c58ba3fdbd880544263ffffffff90811663ffffffff194392909216600160201b02919091166001600160401b031990921691909117179055831561139e57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6113b38382613e15565b6113be838383613f36565b505050565b5f811180156113d3575060148111155b6114195760405162461bcd60e51b8152602060048201526012602482015271496e76616c69642062617463682073697a6560701b60448201526064015b60405180910390fd5b5f5b818110801561142957508281105b156111ac575f84848381811061144157611441615af1565b9050602002013590505f6001600160a01b031661145d826138f6565b6001600160a01b0316148061148357505f818152606a602052604090205463ffffffff16155b15611491575060010161141b565b5f818152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b9004909116606082015291036114fd57505060010161141b565b80515f9062ed4e009061151990670de0b6b3a764000090615c0b565b6115239190615c34565b5f848152606a602052604090205490915063ffffffff1660015b8163ffffffff168163ffffffff161161176e575f858152606b6020908152604080832063ffffffff8086168552925282206001810154909291169003611586575060010161153d565b600181015460408601515f9163ffffffff9081169116116115a7575f6115c1565b600182015460408701516115c19163ffffffff1690615b31565b905062ed4e0063ffffffff8216116115d957806115de565b62ed4e005b90505f62ed4e006115ff670de0b6b3a7640000673782dace9d900000615b8b565b61160f9063ffffffff8516615c0b565b6116199190615c34565b61162b90670de0b6b3a7640000615bd0565b83546001600160801b03908116600160801b8983160217855588519181169250670de0b6b3a76400009161166191849116615b4d565b61166b9190615b78565b83546001600160801b0319166001600160801b039190911617835563ffffffff8581169085161015611760575f888152606b60205260408120816116b0876001615bef565b63ffffffff908116825260208083019390935260409182015f2082516080810184528154600f81810b8352600160801b909104900b9481019490945260010154808216928401839052600160201b90041660608301529091501561175e578354602082015161172991600160801b9004600f0b90615c61565b60408281015163ffffffff165f908152606c6020522080546001600160801b0319166001600160801b03929092169190911790555b505b83600101935050505061153d565b508460010194505050505061141b565b5f61178761391d565b61178f613974565b82804211156117b157604051631ab7da6b60e01b815260040160405180910390fd5b856001600160801b03165f036117da5760405163162908e360e11b815260040160405180910390fd5b63ffffffff851615806117f5575062ed4e0063ffffffff8616115b1561181357604051637616640160e01b815260040160405180910390fd5b6001600160a01b03871661183a5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0387165f90815260676020526040902054606460ff909116106118775760405163133cbc4f60e01b815260040160405180910390fd5b5f6118828642615bef565b90505f5f611891898988613fb9565b915091505f60405180604001604052808b600f0b81526020018563ffffffff1681525090506118de5f60405180604001604052805f600f0b81526020015f63ffffffff16815250836139ba565b6064546040516370a0823160e01b81525f916001600160a01b0316906370a082319061190e9030906004016155c2565b602060405180830381865afa158015611929573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061194d9190615c8e565b606454909150611971906001600160a01b031633306001600160801b038f166140ad565b6119846001600160801b038c1682615baa565b6064546040516370a0823160e01b81526001600160a01b03909116906370a08231906119b49030906004016155c2565b602060405180830381865afa1580156119cf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f39190615c8e565b14611a11576040516312171d8360e31b815260040160405180910390fd5b60658054600163ffffffff600160a01b80840482168381019092160263ffffffff60a01b19909316929092179092556001600160a01b038e165f908152606760205260409020805460ff80821690940190931660ff19909316929092179091559650611a7d8c88614118565b604080516080810182526001600160801b03808e168252868116602080840191825263ffffffff808b16858701908152428216606087019081525f8f8152606690945296909220945192518416600160801b0292909316919091178355516001909201805493518216600160201b026001600160401b03199094169290911691909117919091179055611b11878c85613b23565b604080516001600160801b038d16815263ffffffff8716602082015288916001600160a01b038f16915f516020615f6a5f395f51905f52910160405180910390a3505050505050611b6160015f55565b95945050505050565b611b7261391d565b5f611b7c826138f6565b90506001600160a01b038116611ba457604051626f708760e21b815260040160405180910390fd5b6001600160a01b0381163314611bcd576040516359dc379f60e01b815260040160405180910390fd5b5f828152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529103611c4857604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff161015611c795760405163342ad40160e11b815260040160405180910390fd5b8051606e546001600160801b039081169082161115611ca757606e80546001600160801b0319169055611ce9565b606e80548291905f90611cc49084906001600160801b0316615b8b565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b5f84815260666020908152604080832083815560010180546001600160401b031916905580518082018252600f85900b81528582015163ffffffff168184015281518083019092528382529181019290925290611d4990869083906139ba565b5f858152606a60205260409020805463ffffffff19169055606454611d81906001600160a01b0316336001600160801b038516614131565b611d8a85614161565b335f81815260676020908152604091829020805460ff19811660ff9182165f190190911617905590516001600160801b03851681528792917f8903a5b5d08a841e7f68438387f1da20c84dea756379ed37e633ff3854b99b84910160405180910390a350505050611dfa60015f55565b50565b611e05614199565b6001600160a01b038116611e2c5760405163d92e233d60e01b815260040160405180910390fd5b606d80546001600160a01b0319166001600160a01b0392909216919091179055565b6113be83838360405180602001604052805f815250612330565b611e7061391d565b606f54600160a01b900460ff16611ec15760405162461bcd60e51b81526020600482015260156024820152744e6f7420696e20656d657267656e6379206d6f646560581b6044820152606401611410565b33611ecb82611ffb565b6001600160a01b031614611ef2576040516359dc379f60e01b815260040160405180910390fd5b5f818152606660208181526040808420815160808101835281546001600160801b03808216808452600160801b909204168286015260018301805463ffffffff80821696850196909652600160201b81049095166060840152888852959094529490556001600160401b031916909155611f6b83614161565b335f818152606760205260409020805460ff19811660ff9182165f1901909116179055606454611fb0916001600160a01b03909116906001600160801b038416614131565b6040516001600160801b0382168152839033907f4f27eb511b2a4633cfb633ac1c4a99b4c298ca6488b29ec26f3504a5927f67289060200160405180910390a35050611dfa60015f55565b5f61081c8261388b565b5f5f61200f613867565b90506001600160a01b03831661203a575f6040516322718ad960e21b815260040161141091906155c2565b6001600160a01b039092165f908152600390920160205250604090205490565b612062614199565b61206b5f6141cb565b565b612075614199565b6001600160a01b03811661209c5760405163d92e233d60e01b815260040160405180910390fd5b6065546001600160a01b0316156120ef5760405162461bcd60e51b8152602060048201526017602482015276111a5cdd1c9a589d5d1bdc88185b1c9958591e481cd95d604a1b6044820152606401611410565b606580546001600160a01b0319166001600160a01b0392909216919091179055565b5f818152606660209081526040808320815160808101835281546001600160801b038082168352600160801b90910416938101939093526001015463ffffffff808216928401839052600160201b909104811660608401524216106121805750670de0b6b3a764000092915050565b5f4282604001516121919190615b31565b90505f62ed4e006121b0670de0b6b3a764000063ffffffff8516615b4d565b6121ba9190615b78565b90505f670de0b6b3a7640000826121d982673782dace9d900000615b8b565b6001600160801b03166121ec9190615b4d565b6121f69190615b78565b61220890670de0b6b3a7640000615baa565b905080673782dace9d9000006001600160801b03821611156122385750673782dace9d9000009695505050505050565b670de0b6b3a76400006001600160801b03821610156122655750670de0b6b3a76400009695505050505050565b9695505050505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b60605f6122a8613867565b905080600101805461083d90615ab9565b60695463ffffffff9081165f90815260686020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001015480851691830191909152600160201b900490921660608301529061231e818461423b565b9392505050565b6108de338383614371565b61233a8483613e15565b6111ac84848484614414565b61234e61391d565b612356613974565b808042111561237857604051631ab7da6b60e01b815260040160405180910390fd5b600283101561239a5760405163162908e360e11b815260040160405180910390fd5b5f80805b858110156124a357336123c88888848181106123bc576123bc615af1565b90506020020135611ffb565b6001600160a01b0316146123ef576040516359dc379f60e01b815260040160405180910390fd5b5f60665f89898581811061240557612405615af1565b602090810292909201358352508181019290925260409081015f20815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b9004909116606082015291506124789085615bd0565b93508263ffffffff16816040015163ffffffff16111561249a57806040015192505b5060010161239e565b505f6124af4283615b31565b905062ed4e0063ffffffff821611156124db57604051637616640160e01b815260040160405180910390fd5b5f62ed4e006124fb670de0b6b3a76400006001600160801b038716615b4d565b6125059190615b78565b90505f6065601481819054906101000a900463ffffffff1661252690615ca5565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff1690506125553382614118565b5f5b8881101561263f575f8a8a8381811061257257612572615af1565b602090810292909201355f818152606684526040808220815160808101835281546001600160801b038082168352600160801b909104168188015260019091015463ffffffff808216838501908152600160201b90920481166060840152835180850185528351600f0b81529151168188015282518084019093528383529582019290925291945092915061260a90849083906139ba565b5f83815260666020526040812090815560010180546001600160401b031916905561263483614161565b505050600101612557565b50604080518082018252600f87900b815263ffffffff861660208083019190915282518084019093525f808452908301529061267d908390836139ba565b604080516080810182526001600160801b038089168252858116602080840191825263ffffffff808b16858701908152428216606087019081525f8a815260668552888120975195518716600160801b0295909616949094178655516001958601805494518316600160201b026001600160401b031990951691909216179290921790915533808352606790915290839020805460ff8082168f900390940190931660ff199093169290921790915590518391905f516020615f6a5f395f51905f5290612767908a908a906001600160801b0392909216825263ffffffff16602082015260400190565b60405180910390a3505050505050506113be60015f55565b61278761391d565b61278f613974565b81804211156127b157604051631ab7da6b60e01b815260040160405180910390fd5b5f85815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b900490921660608301528691901580159061282e5750806040015163ffffffff164263ffffffff16105b15612c4b575f4282604001516128449190615b31565b90505f62ed4e00612863670de0b6b3a764000063ffffffff8516615b4d565b61286d9190615b78565b90505f670de0b6b3a76400008261288c82673782dace9d900000615b8b565b6001600160801b031661289f9190615b4d565b6128a99190615b78565b6128bb90670de0b6b3a7640000615baa565b905080673782dace9d9000006001600160801b03821611156128e25750673782dace9d9000005b670de0b6b3a76400006001600160801b03821610156129065750670de0b6b3a76400005b84515f90670de0b6b3a76400009061292b9062ed4e00906001600160801b0316615b78565b6129359190615b4d565b90505f819050806001600160801b031687602001516001600160801b0316141580612977575062015180876060015163ffffffff16426129759190615bbd565b115b15612c445760208701515f906001600160801b031615612a5c575f62ed4e006129ae670de0b6b3a764000063ffffffff8b16615b4d565b6129b89190615b78565b90505f670de0b6b3a7640000826129d782673782dace9d900000615b8b565b6001600160801b03166129ea9190615b4d565b6129f49190615b78565b612a0690670de0b6b3a7640000615baa565b9250829050673782dace9d9000006001600160801b0382161115612a3057673782dace9d90000092505b670de0b6b3a76400006001600160801b0384161015612a5557670de0b6b3a764000092505b5050612a67565b50670de0b6b3a76400005b87515f90670de0b6b3a764000090612a8b906001600160801b038581169116615b4d565b612a959190615b78565b89519091505f90670de0b6b3a764000090612abc906001600160801b038981169116615b4d565b612ac69190615b78565b905081811115612b24575f612adb8383615bbd565b606e805491925082915f90612afa9084906001600160801b0316615bd0565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555050612ba6565b80821115612ba6575f612b378284615bbd565b606e549091506001600160801b0316811115612b6257606e80546001600160801b0319169055612ba4565b606e80548291905f90612b7f9084906001600160801b0316615b8b565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b505b612bf98b60405180604001604052808d5f0151600f0b81526020018d6040015163ffffffff1681525060405180604001604052808e5f0151600f0b81526020018e6040015163ffffffff168152506139ba565b5050505f88815260666020526040902080546001600160801b03808416600160801b029116178155600101805463ffffffff4216600160201b0267ffffffff00000000199091161790555b5050505050505b32612c5588611ffb565b6001600160a01b031614612c945733612c6d88611ffb565b6001600160a01b031614612c94576040516359dc379f60e01b815260040160405180910390fd5b856001600160801b03165f03612cbd5760405163162908e360e11b815260040160405180910390fd5b5f878152606660205260408120805490916001600160801b039091169003612cf857604051632254ea3d60e11b815260040160405180910390fd5b600181015463ffffffff9081164290911610612d27576040516307b7d7dd60e51b815260040160405180910390fd5b6064546040516370a0823160e01b81525f916001600160a01b0316906370a0823190612d579030906004016155c2565b602060405180830381865afa158015612d72573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d969190615c8e565b606454909150612dba906001600160a01b031633306001600160801b038c166140ad565b612dcd6001600160801b03891682615baa565b6064546040516370a0823160e01b81526001600160a01b03909116906370a0823190612dfd9030906004016155c2565b602060405180830381865afa158015612e18573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e3c9190615c8e565b14612e5a576040516312171d8360e31b815260040160405180910390fd5b612e6589898861442c565b50505050506111ac60015f55565b612e7b614199565b606f805460ff60a01b1916600160a01b179055612e96613dcb565b606f546040517fc0a1c7e9f05b4d536e1ff8606bae9b847cdb43ef4a9b2d7a503a88cee08dccdb91612ed3916001600160a01b03909116906155c2565b60405180910390a1565b60605f612ee9836138f6565b6001600160a01b031603612f0f57604051626f708760e21b815260040160405180910390fd5b606d546001600160a01b0316612f38576040516338a69c8d60e21b815260040160405180910390fd5b606d54604051602481018490525f9182916001600160a01b039091169060440160408051601f198184030181529181526020820180516001600160e01b031663c87b56dd60e01b17905251612f8d9190615cc9565b5f60405180830381855afa9150503d805f8114612fc5576040519150601f19603f3d011682016040523d82523d5f602084013e612fca565b606091505b5091509150816130145760405162461bcd60e51b8152602060048201526015602482015274105c9d081c1c9bde1e4818d85b1b0819985a5b1959605a1b6044820152606401611410565b808060200190518101906130289190615cdf565b949350505050565b5f63ffffffff8216158061304c575062ed4e0063ffffffff8316115b1561306a57604051637616640160e01b815260040160405180910390fd5b826001600160801b03165f036130935760405163162908e360e11b815260040160405180910390fd5b5f670de0b6b3a76400006130b362ed4e006001600160801b038716615b78565b6130bd9190615b4d565b9050805f036130d757670de0b6b3a764000091505061081c565b5f62ed4e006130f4670de0b6b3a764000063ffffffff8716615b4d565b6130fe9190615b78565b90505f670de0b6b3a764000061311c81673782dace9d900000615b8b565b61312f906001600160801b031684615b4d565b6131399190615b78565b61314b90670de0b6b3a7640000615baa565b9050673782dace9d900000811161317f57670de0b6b3a764000081106131715780612265565b670de0b6b3a7640000612265565b673782dace9d9000009695505050505050565b5f828152606a602052604081205463ffffffff168082036131b6575f91505061081c565b5f84815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b90049092166060830152158061322f5750806040015163ffffffff168463ffffffff1610155b1561323e575f9250505061081c565b815b60018163ffffffff16106133ea575f868152606b6020908152604080832063ffffffff80861685529083529281902081516080810183528154600f81810b8352600160801b909104900b9381019390935260010154808416918301829052600160201b90048316606083015290918716106133d75760408301515f9062ed4e0090670de0b6b3a7640000906132d6908a90615b31565b63ffffffff166132e69190615b4d565b6132f09190615b78565b90505f670de0b6b3a764000061330e81673782dace9d900000615b8b565b613321906001600160801b031684615b4d565b61332b9190615b78565b61333d90670de0b6b3a7640000615baa565b9050673782dace9d900000811161337157670de0b6b3a76400008110613363578061337b565b670de0b6b3a764000061337b565b673782dace9d9000005b83519091505f90670de0b6b3a7640000906133a09084906001600160801b0316615b4d565b6133aa9190615b78565b90506001600160801b0381116133c057806133c9565b6001600160801b035b97505050505050505061081c565b50806133e281615d53565b915050613240565b505f95945050505050565b606d545f90819063ffffffff600160a01b9091048116908416116134195782613433565b606d5461343390600160a01b900463ffffffff1684615b31565b90506130288482613030565b5f61344861391d565b613450613974565b828042111561347257604051631ab7da6b60e01b815260040160405180910390fd5b856001600160801b03165f0361349b5760405163162908e360e11b815260040160405180910390fd5b63ffffffff851615806134b6575062ed4e0063ffffffff8616115b156134d457604051637616640160e01b815260040160405180910390fd5b335f90815260676020526040902054606460ff909116106135085760405163133cbc4f60e01b815260040160405180910390fd5b5f6135138642615bef565b90505f5f613522898988613fb9565b915091505f60405180604001604052808b600f0b81526020018563ffffffff16815250905061356f5f60405180604001604052805f600f0b81526020015f63ffffffff16815250836139ba565b6064546040516370a0823160e01b81525f916001600160a01b0316906370a082319061359f9030906004016155c2565b602060405180830381865afa1580156135ba573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135de9190615c8e565b606454909150613602906001600160a01b031633306001600160801b038f166140ad565b6136156001600160801b038c1682615baa565b6064546040516370a0823160e01b81526001600160a01b03909116906370a08231906136459030906004016155c2565b602060405180830381865afa158015613660573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136849190615c8e565b146136a2576040516312171d8360e31b815260040160405180910390fd5b60658054600163ffffffff600160a01b80840482168381019092160263ffffffff60a01b1990931692909217909255335f818152606760205260409020805460ff80821690950190941660ff199094169390931790925597506137059088614118565b604080516080810182526001600160801b03808e168252868116602080840191825263ffffffff808b16858701908152428216606087019081525f8f8152606690945296909220945192518416600160801b0292909316919091178355516001909201805493518216600160201b026001600160401b03199094169290911691909117919091179055613799878c85613b23565b604080516001600160801b038d16815263ffffffff87166020820152889133915f516020615f6a5f395f51905f52910160405180910390a350505050505061302860015f55565b5f5f6137ea613867565b6001600160a01b039485165f90815260059190910160209081526040808320959096168252939093525050205460ff1690565b613825614199565b6001600160a01b03811661384e575f604051631e4fbdf760e01b815260040161141091906155c2565b611dfa816141cb565b61385f614199565b61206b6145ff565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930090565b5f5f613896836138f6565b90506001600160a01b03811661081c57604051637e27328960e01b815260048101849052602401611410565b5f5f6138cc613867565b5f938452600401602052505060409020546001600160a01b031690565b6113be8383836001614638565b5f5f613900613867565b5f938452600201602052505060409020546001600160a01b031690565b60025f540361396e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611410565b60025f55565b60325460ff161561206b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401611410565b6139c261473f565b82156113be576113be838383614900565b5f806139eb62ed4e006001600160801b038516615b78565b90506139ff670de0b6b3a764000082615b4d565b90506001600160801b0381111561081c5760405162461bcd60e51b815260206004820152600e60248201526d0a6d8dee0ca40e8dede40d0d2ced60931b6044820152606401611410565b5f826001600160801b03165f03613a695750670de0b6b3a764000061081c565b5f62ed4e00613a86670de0b6b3a764000063ffffffff8616615b4d565b613a909190615b78565b90505f670de0b6b3a7640000613aae81673782dace9d900000615b8b565b613ac1906001600160801b031684615b4d565b613acb9190615b78565b613add90670de0b6b3a7640000615baa565b9050673782dace9d900000811115613b0157673782dace9d9000009250505061081c565b670de0b6b3a764000081101561302857670de0b6b3a76400009250505061081c565b5f838152606660209081526040808320815160808101835281546001600160801b038082168352600160801b9091041693810184905260019091015463ffffffff80821693830193909352600160201b900490911660608201529190613b9157670de0b6b3a7640000613bd1565b428260400151613ba19190615b31565b63ffffffff1682602001516001600160801b0316613bbf9190615b4d565b613bd190670de0b6b3a7640000615baa565b9050673782dace9d9000006001600160801b0382161115613bf75750673782dace9d9000005b670de0b6b3a76400006001600160801b0382161015613c1b5750670de0b6b3a76400005b5f670de0b6b3a7640000613c3b6001600160801b03848116908816615b4d565b613c459190615b78565b90505f670de0b6b3a7640000613c676001600160801b03878116908916615b4d565b613c719190615b78565b905081811115613cf7575f613c868383615bbd565b90506001600160801b03811115613cb057604051630fc12e3560e11b815260040160405180910390fd5b606e80548291905f90613ccd9084906001600160801b0316615bd0565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555050613d79565b80821115613d79575f613d0a8284615bbd565b606e549091506001600160801b0316811115613d3557606e80546001600160801b0319169055613d77565b606e80548291905f90613d529084906001600160801b0316615b8b565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b505b50505050505050565b60015f55565b613d906149f9565b6108de8282614a42565b613da26149f9565b61206b614a6f565b613db26149f9565b61206b614a77565b613dc26149f9565b611dfa81614a8b565b613dd3613974565b6032805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613e083390565b604051612ed391906155c2565b6001600160a01b03821615801590613e3757506065546001600160a01b031615155b8015613e5457505f613e48826138f6565b6001600160a01b031614155b156108de5760655460405163135bb63160e21b8152600481018390525f916001600160a01b031690634d6ed8c490602401602060405180830381865afa158015613ea0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613ec49190615c8e565b11156108de5760655460405163379607f560e01b8152600481018390526001600160a01b039091169063379607f5906024016020604051808303815f875af1158015613f12573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113be9190615c8e565b6001600160a01b038216613f5f575f604051633250574960e11b815260040161141091906155c2565b5f613f6b838333614a93565b9050836001600160a01b0316816001600160a01b0316146111ac576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401611410565b5f8080613fd262ed4e006001600160801b038816615b78565b9050613fe6670de0b6b3a764000082615b4d565b90506001600160801b038111156140305760405162461bcd60e51b815260206004820152600e60248201526d536c6f7065206f766572666c6f7760901b6044820152606401611410565b80925061403d8386613a49565b9150673782dace9d9000006001600160801b038316111561407157604051638f651fb760e01b815260040160405180910390fd5b836001600160801b0316826001600160801b031610156140a457604051638199f5f360e01b815260040160405180910390fd5b50935093915050565b6040516001600160a01b03808516602483015283166044820152606481018290526111ac9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614b92565b6108de828260405180602001604052805f815250614c65565b6040516001600160a01b0383166024820152604481018290526113be90849063a9059cbb60e01b906064016140e1565b5f61416d5f835f614a93565b90506001600160a01b0381166108de57604051637e27328960e01b815260048101839052602401611410565b336141a261226f565b6001600160a01b03161461206b573360405163118cdaa760e01b815260040161141091906155c2565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f5f62093a808085604001516142519190615d71565b61425b9190615d98565b90505f5b60ff81101561434c5761427562093a8083615bef565b91508363ffffffff168263ffffffff1611156142c957604085015161429a9085615b31565b63ffffffff1685602001516142af9190615db7565b855186906142be908390615c61565b600f0b90525061434c565b60408501516142d89083615b31565b63ffffffff1685602001516142ed9190615db7565b855186906142fc908390615c61565b600f90810b90915263ffffffff84165f908152606c602090815260409091205490880180519190920b9250614332908390615dd6565b600f0b90525063ffffffff8216604086015260010161425f565b505f845f0151600f0b121561435f575f84525b505090516001600160801b0316919050565b5f61437a613867565b90506001600160a01b0383166143a55782604051630b61174360e31b815260040161141091906155c2565b6001600160a01b038481165f818152600584016020908152604080832094881680845294825291829020805460ff191687151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b61441f8484846113a9565b6111ac3385858585614c78565b5f838152606660205260408120805490916001600160801b03909116906144538583615bd0565b600184015490915063ffffffff165f61446c4283615b31565b90505f614478846139d3565b90505f6144858284613a49565b90505f6144918b612111565b9050806001600160801b0316826001600160801b0316116144b257806144b4565b815b91506144ca6103e8670de0b6b3a7640000615c34565b6001600160801b03168a6001600160801b03161180156144fb5750886001600160801b0316826001600160801b0316105b1561451957604051638199f5f360e01b815260040160405180910390fd5b61455e8b60405180604001604052808a600f0b81526020018863ffffffff1681525060405180604001604052808a600f0b81526020018963ffffffff168152506139ba565b6001600160801b03838116600160801b0290871617885560018801805463ffffffff4216600160201b0267ffffffff00000000199091161790556145a38b8b84613b23565b604080516001600160801b038c81168252888116602083015284168183015290518c9133917f1381e2f7d0d4b71a58d34dc3db2051dd52769766e65eabf380c9b4ea93f0890b9181900360600190a35050505050505050505050565b614607614d8e565b6032805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33613e08565b5f614641613867565b9050818061465757506001600160a01b03831615155b1561470f575f6146668561388b565b90506001600160a01b038416158015906146925750836001600160a01b0316816001600160a01b031614155b80156146a557506146a381856137e0565b155b156146c5578360405163a9fbf51f60e01b815260040161141091906155c2565b821561470d5784866001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5f93845260040160205250506040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60695463ffffffff16614750615515565b63ffffffff8216156147c95760685f61476a600185615b31565b63ffffffff908116825260208083019390935260409182015f2082516080810184528154600f81810b8352600160801b909104900b948101949094526001015480821692840192909252600160201b90910416606082015290506147f6565b50604080516080810182525f808252602082015263ffffffff428116928201929092524390911660608201525b60408101515f63ffffffff8083164290911611156148575760408301516148239063ffffffff1642615bbd565b60608401516148389063ffffffff1643615bbd565b61484a90670de0b6b3a7640000615b4d565b6148549190615b78565b90505b61486383838387614dd7565b9250614870846001615bef565b6069805463ffffffff92831663ffffffff199091161790558481165f9081526068602090815260408083208751928801516001600160801b03908116600160801b0290841617815590870151600191909101805460608901518616600160201b026001600160401b0319909116929095169190911793909317909255600f9190910b12156111ac5750505f905250565b614908615515565b614910615515565b61491a8483614fe0565b506149258382614fe0565b5061493a84848460200151846020015161512f565b5f858152606a60205260408120546149599063ffffffff166001615bef565b5f878152606a60209081526040808320805463ffffffff95861663ffffffff199091168117909155428516878301908152438616606089019081529b8552606b84528285209185529083529220855195909101516001600160801b03908116600160801b02951694909417845551600193909301805497518216600160201b026001600160401b0319909816939091169290921795909517905550505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661206b57604051631afcd79f60e31b815260040160405180910390fd5b614a4a6149f9565b5f614a53613867565b905080614a608482615e47565b50600181016111ac8382615e47565b613d826149f9565b614a7f6149f9565b6032805460ff19169055565b6138256149f9565b5f5f614a9d613867565b90505f614aa9856138f6565b90506001600160a01b03841615614ac557614ac581858761526a565b6001600160a01b03811615614b0157614ae05f865f5f614638565b6001600160a01b0381165f908152600383016020526040902080545f190190555b6001600160a01b03861615614b31576001600160a01b0386165f9081526003830160205260409020805460010190555b5f85815260028301602052604080822080546001600160a01b0319166001600160a01b038a811691821790925591518893918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a495945050505050565b5f614be6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166152ce9092919063ffffffff16565b905080515f1480614c06575080806020019051810190614c069190615f01565b6113be5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611410565b614c6f83836152dc565b6113be335f8585855b6001600160a01b0383163b15614d8757604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290614cba908890889087908790600401615f1c565b6020604051808303815f875af1925050508015614cf4575060408051601f3d908101601f19168201909252614cf191810190615f4e565b60015b614d52573d808015614d21576040519150601f19603f3d011682016040523d82523d5f602084013e614d26565b606091505b5080515f03614d4a5783604051633250574960e11b815260040161141091906155c2565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14614d855783604051633250574960e11b815260040161141091906155c2565b505b5050505050565b60325460ff1661206b5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401611410565b614ddf615515565b5f62093a80614dee8187615d71565b614df89190615d98565b9050425f5b60ff811015614fd457614e1362093a8084615bef565b92508163ffffffff168363ffffffff161115614e7657614e338783615b31565b63ffffffff168860200151614e489190615db7565b88518990614e57908390615c61565b600f0b90525063ffffffff80831660408a015243166060890152614fd4565b614e808784615b31565b63ffffffff168860200151614e959190615db7565b88518990614ea4908390615c61565b600f90810b90915263ffffffff85165f908152606c6020908152604090912054908b0180519190920b9250614eda908390615dd6565b600f0b90525063ffffffff831660408901819052670de0b6b3a764000090614f029085615b31565b614f1b9063ffffffff166001600160801b038916615b4d565b614f259190615b78565b886060015163ffffffff16614f3a9190615baa565b63ffffffff1660608901528760685f83614f55896001615bef565b614f5f9190615bef565b63ffffffff908116825260208083019390935260409182015f208451938501516001600160801b03908116600160801b02941693909317835590830151600192830180546060909501518316600160201b026001600160401b0319909516919092161792909217909155929650869201614dfd565b50959695505050505050565b5f4263ffffffff16836020015163ffffffff1611158061500257508251600f0b155b1561500e57505f61081c565b5f42846020015161501f9190615b31565b63ffffffff16905062ed4e008111615037578061503c565b62ed4e005b90505f62ed4e0061505d670de0b6b3a7640000673782dace9d900000615b8b565b615070906001600160801b031684615b4d565b61507a9190615b78565b61508c90670de0b6b3a7640000615baa565b9050673782dace9d90000081116150c057670de0b6b3a764000081106150b257806150ca565b670de0b6b3a76400006150ca565b673782dace9d9000005b85519091506001600160801b0316670de0b6b3a76400006150eb8383615b4d565b6150f59190615b78565b600f0b855262ed4e00615110670de0b6b3a764000083615b4d565b61511a9190615b78565b600f0b60208601525060019250505092915050565b4263ffffffff16846020015163ffffffff1611156151d05760208085015163ffffffff165f908152606c9091526040902054600f0b61516e8382615dd6565b9050846020015163ffffffff16846020015163ffffffff1603615198576151958282615c61565b90505b60208581015163ffffffff165f908152606c9091526040902080546001600160801b0319166001600160801b03929092169190911790555b4263ffffffff16836020015163ffffffff1611156111ac57836020015163ffffffff16836020015163ffffffff1611156111ac5760208084015163ffffffff165f908152606c9091526040902054600f0b61522b8282615c61565b60208086015163ffffffff165f908152606c9091526040902080546001600160801b039092166001600160801b03199092169190911790555050505050565b61527583838361533d565b6113be576001600160a01b0383166152a357604051637e27328960e01b815260048101829052602401611410565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401611410565b606061302884845f856153a1565b6001600160a01b038216615305575f604051633250574960e11b815260040161141091906155c2565b5f61531183835f614a93565b90506001600160a01b038116156113be575f6040516339e3563760e11b815260040161141091906155c2565b5f6001600160a01b038316158015906130285750826001600160a01b0316846001600160a01b03161480615376575061537684846137e0565b806130285750826001600160a01b031661538f836138c2565b6001600160a01b031614949350505050565b6060824710156154025760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401611410565b5f5f866001600160a01b0316858760405161541d9190615cc9565b5f6040518083038185875af1925050503d805f8114615457576040519150601f19603f3d011682016040523d82523d5f602084013e61545c565b606091505b509150915061546d87838387615478565b979650505050505050565b606083156154e65782515f036154df576001600160a01b0385163b6154df5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611410565b5081613028565b61302883838151156154fb5781518083602001fd5b8060405162461bcd60e51b81526004016114109190615599565b604080516080810182525f80825260208201819052918101829052606081019190915290565b6001600160e01b031981168114611dfa575f5ffd5b5f60208284031215615560575f5ffd5b813561231e8161553b565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61231e602083018461556b565b5f602082840312156155bb575f5ffd5b5035919050565b6001600160a01b0391909116815260200190565b80356001600160a01b03811681146155ec575f5ffd5b919050565b5f5f60408385031215615602575f5ffd5b61560b836155d6565b946020939093013593505050565b5f60208284031215615629575f5ffd5b61231e826155d6565b602080825282518282018190525f918401906040840190835b8181101561566957835183526020938401939092019160010161564b565b509095945050505050565b803563ffffffff811681146155ec575f5ffd5b5f5f60408385031215615698575f5ffd5b823591506156a860208401615674565b90509250929050565b80356001600160801b03811681146155ec575f5ffd5b5f5f5f5f608085870312156156da575f5ffd5b843593506156ea60208601615674565b9250604085013591506156ff606086016156b1565b905092959194509250565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156157465761574661570a565b604052919050565b5f6001600160401b038211156157665761576661570a565b50601f01601f191660200190565b5f6157866157818461574e565b61571e565b9050828152838383011115615799575f5ffd5b828260208301375f602084830101529392505050565b5f82601f8301126157be575f5ffd5b61231e83833560208501615774565b5f5f5f5f608085870312156157e0575f5ffd5b6157e9856155d6565b93506157f7602086016155d6565b925060408501356001600160401b03811115615811575f5ffd5b61581d878288016157af565b92505060608501356001600160401b03811115615838575f5ffd5b615844878288016157af565b91505092959194509250565b5f5f5f60608486031215615862575f5ffd5b61586b846155d6565b9250615879602085016155d6565b929592945050506040919091013590565b5f5f5f6040848603121561589c575f5ffd5b83356001600160401b038111156158b1575f5ffd5b8401601f810186136158c1575f5ffd5b80356001600160401b038111156158d6575f5ffd5b8660208260051b84010111156158ea575f5ffd5b6020918201979096509401359392505050565b5f5f5f5f5f60a08688031215615911575f5ffd5b61591a866155d6565b9450615928602087016156b1565b935061593660408701615674565b92506060860135915061594b608087016156b1565b90509295509295909350565b5f60208284031215615967575f5ffd5b61231e82615674565b8015158114611dfa575f5ffd5b5f5f6040838503121561598e575f5ffd5b615997836155d6565b915060208301356159a781615970565b809150509250929050565b5f5f5f5f608085870312156159c5575f5ffd5b6159ce856155d6565b93506159dc602086016155d6565b92506040850135915060608501356001600160401b038111156159fd575f5ffd5b8501601f81018713615a0d575f5ffd5b61584487823560208401615774565b5f5f5f5f60808587031215615a2f575f5ffd5b843593506156ea602086016156b1565b5f5f60408385031215615a50575f5ffd5b615a59836156b1565b91506156a860208401615674565b5f5f5f5f60808587031215615a7a575f5ffd5b615a83856156b1565b93506156ea60208601615674565b5f5f60408385031215615aa2575f5ffd5b615aab836155d6565b91506156a8602084016155d6565b600181811c90821680615acd57607f821691505b602082108103615aeb57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201615b2a57615b2a615b05565b5060010190565b63ffffffff828116828216039081111561081c5761081c615b05565b808202811582820484141761081c5761081c615b05565b634e487b7160e01b5f52601260045260245ffd5b5f82615b8657615b86615b64565b500490565b6001600160801b03828116828216039081111561081c5761081c615b05565b8082018082111561081c5761081c615b05565b8181038181111561081c5761081c615b05565b6001600160801b03818116838216019081111561081c5761081c615b05565b63ffffffff818116838216019081111561081c5761081c615b05565b6001600160801b038181168382160290811690818114615c2d57615c2d615b05565b5092915050565b5f6001600160801b03831680615c4c57615c4c615b64565b806001600160801b0384160491505092915050565b600f82810b9082900b0360016001607f1b0319811260016001607f1b038213171561081c5761081c615b05565b5f60208284031215615c9e575f5ffd5b5051919050565b5f63ffffffff821663ffffffff8103615cc057615cc0615b05565b60010192915050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615cef575f5ffd5b81516001600160401b03811115615d04575f5ffd5b8201601f81018413615d14575f5ffd5b8051615d226157818261574e565b818152856020838501011115615d36575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f63ffffffff821680615d6857615d68615b05565b5f190192915050565b5f63ffffffff831680615d8657615d86615b64565b8063ffffffff84160491505092915050565b63ffffffff8181168382160290811690818114615c2d57615c2d615b05565b5f82600f0b82600f0b0280600f0b9150808214615c2d57615c2d615b05565b600f81810b9083900b0160016001607f1b03811360016001607f1b03198212171561081c5761081c615b05565b601f8211156113be57805f5260205f20601f840160051c81016020851015615e285750805b601f840160051c820191505b81811015614d87575f8155600101615e34565b81516001600160401b03811115615e6057615e6061570a565b615e7481615e6e8454615ab9565b84615e03565b6020601f821160018114615ea6575f8315615e8f5750848201515b5f19600385901b1c1916600184901b178455614d87565b5f84815260208120601f198516915b82811015615ed55787850151825560209485019460019092019101615eb5565b5084821015615ef257868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215615f11575f5ffd5b815161231e81615970565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f906122659083018461556b565b5f60208284031215615f5e575f5ffd5b815161231e8161553b56fedbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f8597828934954a26469706673582212206c7cfd799d498e0dfe91275b4c271b021d906df60b72e04d91b2a212e82147b964736f6c634300081b0033
Deployed Bytecode Sourcemap
151835:39810:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101704:316;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;101704:316:0;;;;;;;;102604:149;;;:::i;:::-;;;;;;;:::i;103892:158::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;103711:115::-;;;;;;:::i;:::-;;:::i;:::-;;186352:104;186436:12;;-1:-1:-1;;;;;186436:12:0;186352:104;;186839:562;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;153996:68::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;153996:68:0;;;;;;;;;;-1:-1:-1;;;153996:68:0;;;;;;;;;3797:2:1;3786:22;;;3768:41;;3845:22;;;;3840:2;3825:18;;3818:50;3916:10;3904:23;;;3884:18;;;3877:51;;;;3964:23;;;3959:2;3944:18;;3937:51;3755:3;3740:19;153996:68:0;3545:449:1;173567:1764:0;;;;;;:::i;:::-;;:::i;155603:736::-;;;;;;:::i;:::-;;:::i;186464:96::-;186538:14;;-1:-1:-1;;;186538:14:0;;;;186464:96;;167234:191;;;;;;:::i;:::-;;:::i;189609:2031::-;;;;;;:::i;:::-;;:::i;186568:109::-;186649:20;;-1:-1:-1;;;;;186649:20:0;186568:109;;;-1:-1:-1;;;;;7834:47:1;;;7816:66;;7804:2;7789:18;186568:109:0;7670:218:1;187904:1695:0;;;;;;:::i;:::-;;:::i;:::-;;;8566:25:1;;;8554:2;8539:18;187904:1695:0;8420:177:1;167667:1491:0;;;;;;:::i;:::-;;:::i;186685:146::-;;;;;;:::i;:::-;;:::i;105278:134::-;;;;;;:::i;:::-;;:::i;185536:585::-;;;;;;:::i;:::-;;:::i;154123:23::-;;;;;-1:-1:-1;;;;;154123:23:0;;;154071:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;8964:2:1;8953:22;;;;8935:41;;8923:2;8908:18;154071:45:0;8791:191:1;145967:86:0;146038:7;;;;145967:86;;102417:120;;;;;;:::i;:::-;;:::i;102084:271::-;;;;;;:::i;:::-;;:::i;150262:103::-;;;:::i;156347:280::-;;;;;;:::i;:::-;;:::i;153722:46::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;153722:46:0;;;;-1:-1:-1;;;153722:46:0;;;;;;;;;-1:-1:-1;;;153722:46:0;;;;;;;;;-1:-1:-1;;;;;9232:47:1;;;9214:66;;9316:47;;;;9311:2;9296:18;;9289:75;9412:10;9400:23;;;9380:18;;;9373:51;;;;9460:23;9455:2;9440:18;;9433:51;9201:3;9186:19;153722:46:0;8987:503:1;160222:1073:0;;;;;;:::i;:::-;;:::i;149527:147::-;;;:::i;153864:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;153864:44:0;;;;;;;;;;-1:-1:-1;;;153864:44:0;;;;;153915:19;;;;;;;;;;;;9669:10:1;9657:23;;;9639:42;;9627:2;9612:18;153915:19:0;9495:192:1;102822:153:0;;;:::i;179559:199::-;;;;;;:::i;:::-;;:::i;186228:116::-;;;;;;:::i;:::-;-1:-1:-1;;;;;186316:20:0;186291:5;186316:20;;;:14;:20;;;;;;;;;186228:116;;;;9864:4:1;9852:17;;;9834:36;;9822:2;9807:18;186228:116:0;9692:184:1;104122:146:0;;;;;;:::i;:::-;;:::i;167433:226::-;;;;;;:::i;:::-;;:::i;180420:2466::-;;;;;;:::i;:::-;;:::i;153776:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;178399:1152;;;;;;:::i;:::-;;:::i;185356:172::-;;;:::i;187405:495::-;;;;;;:::i;:::-;;:::i;184008:782::-;;;;;;:::i;:::-;;:::i;182894:1106::-;;;;;;:::i;:::-;;:::i;185049:271::-;;;;;;:::i;:::-;;:::i;171759:1800::-;;;;;;:::i;:::-;;:::i;153941:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;104339:213;;;;;;:::i;:::-;;:::i;150520:220::-;;;;;;:::i;:::-;;:::i;186129:68::-;;;:::i;101704:316::-;101817:4;-1:-1:-1;;;;;;101854:40:0;;-1:-1:-1;;;101854:40:0;;:105;;-1:-1:-1;;;;;;;101911:48:0;;-1:-1:-1;;;101911:48:0;101854:105;:158;;;-1:-1:-1;;;;;;;;;;99727:40:0;;;101976:36;101834:178;101704:316;-1:-1:-1;;101704:316:0:o;102604:149::-;102649:13;102675:23;102701:19;:17;:19::i;:::-;102675:45;;102738:1;:7;;102731:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102604:149;:::o;103892:158::-;103959:7;103979:22;103993:7;103979:13;:22::i;:::-;;104021:21;104034:7;104021:12;:21::i;103711:115::-;103783:35;103792:2;103796:7;25439:10;103783:8;:35::i;:::-;103711:115;;:::o;186839:562::-;-1:-1:-1;;;;;186952:21:0;;186938:11;186952:21;;;:14;:21;;;;;;186900:25;;186952:21;;;-1:-1:-1;;;;;186995:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;186995:20:0;;186984:31;;187030:5;:10;;187039:1;187030:10;187026:31;;187042:15;186839:562;;;:::o;187026:31::-;187078:20;;187113:245;187139:12;;-1:-1:-1;;;187139:12:0;;;;187134:17;;187113:245;;;187194:5;-1:-1:-1;;;;;187178:21:0;:12;187187:2;187178:8;:12::i;:::-;-1:-1:-1;;;;;187178:21:0;;187174:173;;187245:2;187220:8;187229:12;187220:22;;;;;;;;:::i;:::-;;;;;;;;;;:27;187266:14;;;;:::i;:::-;;;;187319:5;187303:21;;:12;:21;187299:32;187326:5;187299:32;;187153:4;;187113:245;;;;187378:15;;186839:562;;;:::o;173567:1764::-;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;173765:8:::2;156727;156709:15;:26;156705:56;;;156744:17;;-1:-1:-1::0;;;156744:17:0::2;;;;;;;;;;;156705:56;156833:24:::3;156860:15:::0;;;:6:::3;:15;::::0;;;;;;;;156833:42;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;156833:42:0;;::::3;::::0;;;-1:-1:-1;;;156833:42:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;156833:42:0;::::3;::::0;;::::3;::::0;;;;173780:7;;156833:42;156890:15;;;;:57:::3;;;156935:4;:12;;;156909:38;;156916:15;156909:38;;;156890:57;156886:3309;;;157047:15;157087;157065:4;:12;;;:38;;;;:::i;:::-;157047:56:::0;-1:-1:-1;157204:17:0::3;153164:8;157225:29;153370:4;157224:41;157225:17:::0;::::3;:29;:::i;:::-;157224:41;;;;:::i;:::-;157204:61:::0;-1:-1:-1;157280:22:0::3;153370:4;157204:61:::0;157332:32:::3;153370:4:::0;153268::::3;157332:32;:::i;:::-;-1:-1:-1::0;;;;;157324:41:0::3;:53;;;;:::i;:::-;157323:67;;;;:::i;:::-;157305:85;::::0;153322:4:::3;157305:85;:::i;:::-;157280:110:::0;-1:-1:-1;157280:110:0;153268:4:::3;-1:-1:-1::0;;;;;157485:30:0;::::3;;157481:66;;;-1:-1:-1::0;153268:4:0::3;157481:66;153322:4;-1:-1:-1::0;;;;;157566:31:0;::::3;;157562:68;;;-1:-1:-1::0;153322:4:0::3;157562:68;157762:11:::0;;157733:17:::3;::::0;153370:4:::3;::::0;157754:30:::3;::::0;153164:8:::3;::::0;-1:-1:-1;;;;;157754:20:0::3;:30;:::i;:::-;157753:44;;;;:::i;:::-;157733:64;;157812:16;157839:9;157812:37;;157985:8;-1:-1:-1::0;;;;;157971:22:0::3;:4;:10;;;-1:-1:-1::0;;;;;157971:22:0::3;;;:70;;;;158035:6;158016:4;:15;;;157998:33;;:15;:33;;;;:::i;:::-;157997:44;157971:70;157967:2217;;;158164:10;::::0;::::3;::::0;158120:21:::3;::::0;-1:-1:-1;;;;;158164:14:0::3;::::0;158160:591:::3;;158203:20;153164:8;158227:29;153370:4;158226:41;158227:17:::0;::::3;:29;:::i;:::-;158226:41;;;;:::i;:::-;158203:64:::0;-1:-1:-1;158290:25:0::3;153370:4;158203:64:::0;158345:32:::3;153370:4:::0;153268::::3;158345:32;:::i;:::-;-1:-1:-1::0;;;;;158337:41:0::3;:56;;;;:::i;:::-;158336:70;;;;:::i;:::-;158318:88;::::0;153322:4:::3;158318:88;:::i;:::-;158290:116:::0;-1:-1:-1;158290:116:0;;-1:-1:-1;153268:4:0::3;-1:-1:-1::0;;;;;158498:30:0;::::3;;158494:66;;;153268:4;158530:30;;158494:66;153322:4;-1:-1:-1::0;;;;;158587:31:0;::::3;;158583:68;;;153322:4;158620:31;;158583:68;158180:491;;158160:591;;;-1:-1:-1::0;153322:4:0::3;158160:591;158824:11:::0;;158787:25:::3;::::0;153370:4:::3;::::0;158816:36:::3;::::0;-1:-1:-1;;;;;158816:36:0;;::::3;::::0;:20:::3;:36;:::i;:::-;158815:50;;;;:::i;:::-;158921:11:::0;;158787:78;;-1:-1:-1;158884:25:0::3;::::0;153370:4:::3;::::0;158913:36:::3;::::0;-1:-1:-1;;;;;158913:36:0;;::::3;::::0;:20:::3;:36;:::i;:::-;158912:50;;;;:::i;:::-;158884:78;;159084:17;159064;:37;159060:617;;;159126:16;159145:37;159165:17:::0;159145;:37:::3;:::i;:::-;159205:20;:41:::0;;159126:56;;-1:-1:-1;159126:56:0;;159205:20:::3;::::0;:41:::3;::::0;159126:56;;-1:-1:-1;;;;;159205:41:0::3;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;159205:41:0::3;;;;;-1:-1:-1::0;;;;;159205:41:0::3;;;;;;159103:163;159060:617;;;159296:17;159276;:37;159272:405;;;159338:16;159357:37;159377:17:::0;159357;:37:::3;:::i;:::-;159432:20;::::0;159338:56;;-1:-1:-1;;;;;;159432:20:0::3;159421:31:::0;::::3;159417:241;;;159481:20;:24:::0;;-1:-1:-1;;;;;;159481:24:0::3;::::0;;159417:241:::3;;;159593:20;:41:::0;;159625:8;;159593:20;::::3;::::0;:41:::3;::::0;159625:8;;-1:-1:-1;;;;;159593:41:0::3;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;159593:41:0::3;;;;;-1:-1:-1::0;;;;;159593:41:0::3;;;;;;159417:241;159315:362;159272:405;159765:220;159799:7;159829:57;;;;;;;;159858:4;:11;;;159829:57;;;;;;159873:4;:12;;;159829:57;;;;::::0;159909::::3;;;;;;;;159938:4;:11;;;159909:57;;;;;;159953:4;:12;;;159909:57;;;;::::0;159765:11:::3;:220::i;:::-;-1:-1:-1::0;;;160065:15:0::3;::::0;;;:6:::3;:15;::::0;;;;:32;;-1:-1:-1;;;;;160065:32:0;;::::3;-1:-1:-1::0;;;160065:32:0::3;::::0;::::3;;::::0;;-1:-1:-1;160116:26:0::3;:52:::0;;::::3;160152:15;160116:52;-1:-1:-1::0;;;160116:52:0::3;-1:-1:-1::0;;160116:52:0;;::::3;;::::0;;157967:2217:::3;156949:3246;;;;;;156886:3309;173824:10:::4;173804:16;173812:7:::0;173804::::4;:16::i;:::-;-1:-1:-1::0;;;;;173804:30:0::4;;173800:58;;173843:15;;-1:-1:-1::0;;;173843:15:0::4;;;;;;;;;;;173800:58;173879:24;173906:15:::0;;;:6:::4;:15;::::0;;;;;;;173879:42;;::::4;::::0;::::4;::::0;;;;-1:-1:-1;;;;;173879:42:0;;::::4;::::0;;;-1:-1:-1;;;173879:42:0;;::::4;;::::0;;::::4;::::0;;;;;;;::::4;::::0;::::4;::::0;;::::4;::::0;;;;;;;-1:-1:-1;;;173879:42:0;::::4;::::0;;::::4;::::0;;;;;173936:16;173932:44:::4;;173961:15;;-1:-1:-1::0;;;173961:15:0::4;;;;;;;;;;;173932:44;174032:17;174067:18;174052:4;:12;;;:33;;;;:::i;:::-;174032:53:::0;-1:-1:-1;174096:29:0::4;174128:36;174148:15;174032:53:::0;174128:36:::4;:::i;:::-;174096:68:::0;-1:-1:-1;153164:8:0::4;174179:32;::::0;::::4;;174175:62;;;174220:17;;-1:-1:-1::0;;;174220:17:0::4;;;;;;;;;;;174175:62;174325:16;174344:31;174363:4;:11;;;174344:18;:31::i;:::-;174325:50;;174386:18;174407:54;174428:8;174438:22;174407:20;:54::i;:::-;174386:75;;174489:13;-1:-1:-1::0;;;;;174476:26:0::4;:10;-1:-1:-1::0;;;;;174476:26:0::4;;174472:57;;;174511:18;;-1:-1:-1::0;;;174511:18:0::4;;;;;;;;;;;174472:57;174585:55;174607:7;174616:4;:11;;;174629:10;174585:21;:55::i;:::-;174684:314;174710:7;174732:121;;;;;;;;174788:4;:11;;;174732:121;;;;;;174825:4;:12;;;174732:121;;;;::::0;174868:119:::4;;;;;;;;174924:4;:11;;;174868:119;;;;;;174961:10;174868:119;;;;::::0;174684:11:::4;:314::i;:::-;175067:173;;;;;;;;175103:4;:11;;;-1:-1:-1::0;;;;;175067:173:0::4;;;;;175220:8;-1:-1:-1::0;;;;;175067:173:0::4;;;;;175138:10;175067:173;;;;;;175182:15;175067:173;;;;::::0;175049:6:::4;:15;175056:7;175049:15;;;;;;;;;;;:191;;;;;;;;;;;;;-1:-1:-1::0;;;;;175049:191:0::4;;;;;-1:-1:-1::0;;;;;175049:191:0::4;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;175049:191:0::4;;;;;-1:-1:-1::0;;;;;175049:191:0::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;175291:7;175279:10;-1:-1:-1::0;;;;;175266:57:0::4;;175300:10;175312;175266:57;;;;;;15046:10:1::0;15034:23;;;;15016:42;;-1:-1:-1;;;;;15094:47:1;15089:2;15074:18;;15067:75;15004:2;14989:18;;14844:304;175266:57:0::4;;;;;;;;173789:1542;;;;;156822:3392:::3;156772:1;145602::::2;143081:20:::0;142298:1;143601:7;:22;143418:213;143081:20;173567:1764;;;;:::o;155603:736::-;24569:21;19885:15;;-1:-1:-1;;;19885:15:0;;;;19884:16;;-1:-1:-1;;;;;19932:14:0;19738:30;20317:16;;:34;;;;;20337:14;20317:34;20297:54;;20362:17;20382:11;-1:-1:-1;;;;;20382:16:0;20397:1;20382:16;:50;;;;-1:-1:-1;20410:4:0;20402:25;:30;20382:50;20362:70;;20450:12;20449:13;:30;;;;;20467:12;20466:13;20449:30;20445:93;;;20503:23;;-1:-1:-1;;;20503:23:0;;;;;;;;;;;20445:93;20548:18;;-1:-1:-1;;;;;;20548:18:0;20565:1;20548:18;;;20577:69;;;;20612:22;;-1:-1:-1;;;;20612:22:0;-1:-1:-1;;;20612:22:0;;;20577:69;-1:-1:-1;;;;;155799:26:0;::::1;::::0;;:77:::1;;-1:-1:-1::0;;;;;;155845:31:0;::::1;::::0;155799:77:::1;155795:103;;;155885:13;;-1:-1:-1::0;;;155885:13:0::1;;;;;;;;;;;155795:103;155923:27;155937:4;155943:6;155923:13;:27::i;:::-;155961:24;:22;:24::i;:::-;155996:17;:15;:17::i;:::-;156024:26;156039:10;156024:14;:26::i;:::-;156063:8;:6;:8::i;:::-;156082:12;:46:::0;;-1:-1:-1;;;;;156082:46:0;;::::1;-1:-1:-1::0;;;;;;156082:46:0;;::::1;;::::0;;;156139:25:::1;:45:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;156082:12:::1;156234:15:::0;;:12:::1;:15;::::0;:19;:42;;156315:15:::1;156234;156287:44:::0;;::::1;-1:-1:-1::0;;156263:12:0::1;156234:42:::0;;;::::1;-1:-1:-1::0;;;156234:42:0::1;156287:44:::0;;;;-1:-1:-1;;;;;;156287:44:0;;;;;;;::::1;::::0;;20668:104;;;;20703:23;;-1:-1:-1;;;;20703:23:0;;;20746:14;;-1:-1:-1;15306:50:1;;20746:14:0;;15294:2:1;15279:18;20746:14:0;;;;;;;20668:104;19670:1109;;;;;155603:736;;;;:::o;167234:191::-;167334:35;167355:4;167361:7;167334:20;:35::i;:::-;167380:36;167399:4;167404:2;167408:7;167380:18;:36::i;:::-;167234:191;;;:::o;189609:2031::-;189722:1;189710:9;:13;:32;;;;;189740:2;189727:9;:15;;189710:32;189702:63;;;;-1:-1:-1;;;189702:63:0;;15569:2:1;189702:63:0;;;15551:21:1;15608:2;15588:18;;;15581:30;-1:-1:-1;;;15627:18:1;;;15620:48;15685:18;;189702:63:0;;;;;;;;;189783:9;189778:1859;189802:9;189798:1;:13;:36;;;;-1:-1:-1;189815:19:0;;;189798:36;189778:1859;;;189848:15;189866:8;;189875:1;189866:11;;;;;;;:::i;:::-;;;;;;;189848:29;;189975:1;-1:-1:-1;;;;;189946:31:0;:17;189955:7;189946:8;:17::i;:::-;-1:-1:-1;;;;;189946:31:0;;:63;;;-1:-1:-1;189981:23:0;;;;:14;:23;;;;;;;;:28;189946:63;189942:136;;;-1:-1:-1;190038:3:0;;189778:1859;;189942:136;190090:24;190117:15;;;:6;:15;;;;;;;;190090:42;;;;;;;;;-1:-1:-1;;;;;190090:42:0;;;;;;-1:-1:-1;;;190090:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;190090:42:0;;;;;;;;;;190147:16;190143:89;;-1:-1:-1;;190192:3:0;;189778:1859;;190143:89;190308:11;;190283:13;;153164:8;;190308:23;;153370:4;;190308:23;:::i;:::-;190307:35;;;;:::i;:::-;190354:16;190373:23;;;:14;:23;;;;;;190283:60;;-1:-1:-1;190373:23:0;;;190435:1157;190481:9;190465:25;;:12;:25;;;190435:1157;;190508:19;190530:25;;;:16;:25;;;;;;;;:39;;;;;;;;;;190588:8;;;;190530:39;;190588:8;;:13;;190584:109;;-1:-1:-1;190634:14:0;;190435:1157;;190584:109;190790:8;;;;190775:12;;;;190757:15;;190790:8;;;;190775:23;;;:53;;190827:1;190775:53;;;190816:8;;;;190801:12;;;;:23;;190816:8;;;190801:23;:::i;:::-;190757:71;-1:-1:-1;153164:8:0;190854:18;;;;:39;;190885:8;190854:39;;;153164:8;190854:39;190843:50;-1:-1:-1;190908:18:0;153164:8;190961:32;153322:4;153268;190961:32;:::i;:::-;190949:45;;;;;;:::i;:::-;190948:57;;;;:::i;:::-;190929:77;;153322:4;190929:77;:::i;:::-;191071:27;;-1:-1:-1;;;;;191071:27:0;;;-1:-1:-1;;;191071:27:0;;;;;;;191142:11;;190908:98;;;;-1:-1:-1;153370:4:0;;191142:24;;190908:98;;191142:24;;:::i;:::-;191141:38;;;;:::i;:::-;191113:68;;-1:-1:-1;;;;;;191113:68:0;-1:-1:-1;;;;;191113:68:0;;;;;;;191254:24;;;;;;;;191250:274;;;191299:22;191324:25;;;:16;:25;;;;;191299:22;191350:16;:12;191365:1;191350:16;:::i;:::-;191324:43;;;;;;;;;;;;;;;;;;-1:-1:-1;191324:43:0;191299:68;;;;;;;;;;;;;;;-1:-1:-1;;;191299:68:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;191299:68:0;;;;;;;;;-1:-1:-1;191390:16:0;191386:123;;191478:11;;191460:15;;;;:29;;-1:-1:-1;;;191478:11:0;;;;;191460:29;:::i;:::-;191444:12;;;;;191431:26;;;;;;:12;:26;;;:58;;-1:-1:-1;;;;;;191431:58:0;-1:-1:-1;;;;;191431:58:0;;;;;;;;;;191386:123;191280:244;191250:274;191564:14;;;;;190493:1099;;;190435:1157;;;;191624:3;;;;;189837:1800;;;;189778:1859;;187904:1695;188121:15;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;188102:8:::2;156727;156709:15;:26;156705:56;;;156744:17;;-1:-1:-1::0;;;156744:17:0::2;;;;;;;;;;;156705:56;188149:6:::3;-1:-1:-1::0;;;;;188149:11:0::3;188159:1;188149:11:::0;188145:39:::3;;188169:15;;-1:-1:-1::0;;;188169:15:0::3;;;;;;;;;;;188145:39;188195:17;::::0;::::3;::::0;;:43:::3;;-1:-1:-1::0;153164:8:0::3;188216:22;::::0;::::3;;188195:43;188191:73;;;188247:17;;-1:-1:-1::0;;;188247:17:0::3;;;;;;;;;;;188191:73;-1:-1:-1::0;;;;;188275:23:0;::::3;188271:49;;188307:13;;-1:-1:-1::0;;;188307:13:0::3;;;;;;;;;;;188271:49;-1:-1:-1::0;;;;;188331:25:0;::::3;;::::0;;;:14:::3;:25;::::0;;;;;153425:3:::3;188331:47;:25:::0;;::::3;:47;188327:77;;188387:17;;-1:-1:-1::0;;;188387:17:0::3;;;;;;;;;;;188327:77;188417:17;188437:38;188463:12:::0;188444:15:::3;188437:38;:::i;:::-;188417:58;;188489:13;188504:18;188526:61;188551:6;188559:12;188573:13;188526:24;:61::i;:::-;188488:99;;;;188632:28;188663:90;;;;;;;;188711:6;188663:90;;;;;;188735:10;188663:90;;;;::::0;188632:121:::3;;188808:44;188820:1;188823:19;;;;;;;;188837:1;188823:19;;;;;;188840:1;188823:19;;;;::::0;188844:7:::3;188808:11;:44::i;:::-;188929:12;::::0;:37:::3;::::0;-1:-1:-1;;;188929:37:0;;188905:21:::3;::::0;-1:-1:-1;;;;;188929:12:0::3;::::0;:22:::3;::::0;:37:::3;::::0;188960:4:::3;::::0;188929:37:::3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;188973:12;::::0;188905:61;;-1:-1:-1;188973:64:0::3;::::0;-1:-1:-1;;;;;188973:12:0::3;189003:10;189023:4;-1:-1:-1::0;;;;;188973:64:0;::::3;:29;:64::i;:::-;189089:22;-1:-1:-1::0;;;;;189089:22:0;::::3;:13:::0;:22:::3;:::i;:::-;189048:12;::::0;:37:::3;::::0;-1:-1:-1;;;189048:37:0;;-1:-1:-1;;;;;189048:12:0;;::::3;::::0;:22:::3;::::0;:37:::3;::::0;189079:4:::3;::::0;189048:37:::3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:63;189044:102;;189130:16;;-1:-1:-1::0;;;189130:16:0::3;;;;;;;;;;;189044:102;189190:12;:14:::0;;::::3;;-1:-1:-1::0;;;189190:14:0;;::::3;::::0;::::3;::::0;;::::3;::::0;;::::3;;-1:-1:-1::0;;;;189190:14:0;;::::3;::::0;;;::::3;::::0;;;-1:-1:-1;;;;;189215:25:0;::::3;-1:-1:-1::0;189215:25:0;;;:14:::3;:25;::::0;;;;:27;;::::3;::::0;;::::3;::::0;;::::3;::::0;;::::3;-1:-1:-1::0;;189215:27:0;;::::3;::::0;;;::::3;::::0;;;189190:14;-1:-1:-1;189262:29:0::3;189230:9:::0;189190:14;189262:9:::3;:29::i;:::-;189322:145;::::0;;::::3;::::0;::::3;::::0;;-1:-1:-1;;;;;189322:145:0;;::::3;::::0;;;;::::3;;::::0;;::::3;::::0;;;::::3;::::0;;::::3;::::0;;;;;;189420:15:::3;189322:145:::0;::::3;::::0;;;;;;-1:-1:-1;189304:15:0;;;:6:::3;:15:::0;;;;;;;:163;;;;;::::3;-1:-1:-1::0;;;189304:163:0::3;::::0;;;::::3;::::0;;;::::3;::::0;;;;;;::::3;::::0;;;;;::::3;-1:-1:-1::0;;;189304:163:0::3;-1:-1:-1::0;;;;;;189304:163:0;;;;;;::::3;::::0;;;;;;;::::3;::::0;;189480:50:::3;189311:7:::0;189354:6;189519:10;189480:21:::3;:50::i;:::-;189548:47;::::0;;-1:-1:-1;;;;;16901:47:1;;16883:66;;16997:10;16985:23;;16980:2;16965:18;;16958:51;189567:7:0;;-1:-1:-1;;;;;189548:47:0;::::3;::::0;-1:-1:-1;;;;;;;;;;;189548:47:0;16856:18:1;189548:47:0::3;;;;;;;188138:1461;;;;;145602:1:::2;143081:20:::0;142298:1;143601:7;:22;143418:213;143081:20;187904:1695;;;;;;;:::o;167667:1491::-;143037:21;:19;:21::i;:::-;167735:13:::1;167751:17;167760:7;167751:8;:17::i;:::-;167735:33:::0;-1:-1:-1;;;;;;167783:19:0;::::1;167779:48;;167811:16;;-1:-1:-1::0;;;167811:16:0::1;;;;;;;;;;;167779:48;-1:-1:-1::0;;;;;167842:19:0;::::1;167851:10;167842:19;167838:47;;167870:15;;-1:-1:-1::0;;;167870:15:0::1;;;;;;;;;;;167838:47;167906:24;167933:15:::0;;;:6:::1;:15;::::0;;;;;;;167906:42;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;167906:42:0;;::::1;::::0;;;-1:-1:-1;;;167906:42:0;;::::1;;::::0;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;167906:42:0;::::1;::::0;;::::1;::::0;;;;;167963:16;167959:44:::1;;167988:15;;-1:-1:-1::0;;;167988:15:0::1;;;;;;;;;;;167959:44;168044:4;:12;;;168018:38;;168025:15;168018:38;;;168014:67;;;168065:16;;-1:-1:-1::0;;;168065:16:0::1;;;;;;;;;;;168014:67;168119:11:::0;;168238:20:::1;::::0;-1:-1:-1;;;;;168238:20:0;;::::1;168229:29:::0;;::::1;;168225:149;;;168275:20;:24:::0;;-1:-1:-1;;;;;;168275:24:0::1;::::0;;168225:149:::1;;;168332:20;:30:::0;;168356:6;;168332:20;::::1;::::0;:30:::1;::::0;168356:6;;-1:-1:-1;;;;;168332:30:0::1;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;168332:30:0::1;;;;;-1:-1:-1::0;;;;;168332:30:0::1;;;;;;168225:149;168430:15;::::0;;;:6:::1;:15;::::0;;;;;;;168423:22;;;;::::1;::::0;;-1:-1:-1;;;;;;168423:22:0;;;168532:104;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;168612:12;;::::1;::::0;168423:22:::1;168532:104;::::0;;::::1;::::0;168730:19;;;;::::1;::::0;;;;;;;;::::1;::::0;;;;168532:104;168700:50:::1;::::0;168437:7;;168532:104;;168700:11:::1;:50::i;:::-;168815:23;::::0;;;:14:::1;:23;::::0;;;;168808:30;;-1:-1:-1;;168808:30:0::1;::::0;;168906:12:::1;::::0;:45:::1;::::0;-1:-1:-1;;;;;168906:12:0::1;168932:10;-1:-1:-1::0;;;;;168906:45:0;::::1;:25;:45::i;:::-;168998:14;169004:7;168998:5;:14::i;:::-;169063:10;169048:26;::::0;;;:14:::1;:26;::::0;;;;;;;;:28;;-1:-1:-1;;169048:28:0;::::1;;::::0;;::::1;-1:-1:-1::0;;169048:28:0;;;::::1;;::::0;;169113:37;;-1:-1:-1;;;;;7834:47:1;;7816:66;;169134:7:0;;169063:10;169113:37:::1;::::0;7789:18:1;169113:37:0::1;;;;;;;167724:1434;;;;143081:20:::0;142298:1;143601:7;:22;143418:213;143081:20;167667:1491;:::o;186685:146::-;149413:13;:11;:13::i;:::-;-1:-1:-1;;;;;186755:23:0;::::1;186751:49;;186787:13;;-1:-1:-1::0;;;186787:13:0::1;;;;;;;;;;;186751:49;186807:8;:20:::0;;-1:-1:-1;;;;;;186807:20:0::1;-1:-1:-1::0;;;;;186807:20:0;;;::::1;::::0;;;::::1;::::0;;186685:146::o;105278:134::-;105365:39;105382:4;105388:2;105392:7;105365:39;;;;;;;;;;;;:16;:39::i;185536:585::-;143037:21;:19;:21::i;:::-;185621:14:::1;::::0;-1:-1:-1;;;185621:14:0;::::1;;;185613:48;;;::::0;-1:-1:-1;;;185613:48:0;;17222:2:1;185613:48:0::1;::::0;::::1;17204:21:1::0;17261:2;17241:18;;;17234:30;-1:-1:-1;;;17280:18:1;;;17273:51;17341:18;;185613:48:0::1;17020:345:1::0;185613:48:0::1;185696:10;185676:16;185684:7:::0;185676::::1;:16::i;:::-;-1:-1:-1::0;;;;;185676:30:0::1;;185672:58;;185715:15;;-1:-1:-1::0;;;185715:15:0::1;;;;;;;;;;;185672:58;185751:24;185778:15:::0;;;:6:::1;:15;::::0;;;;;;;185751:42;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;185751:42:0;;::::1;::::0;;;-1:-1:-1;;;185751:42:0;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;185751:42:0;::::1;::::0;;::::1;::::0;;;;185860:15;;;;;;;185853:22;;;-1:-1:-1;;;;;;185853:22:0;;;;185886:14:::1;185785:7:::0;185886:5:::1;:14::i;:::-;185951:10;185936:26;::::0;;;:14:::1;:26;::::0;;;;:28;;-1:-1:-1;;185936:28:0;::::1;;::::0;;::::1;-1:-1:-1::0;;185936:28:0;;;::::1;;::::0;;185996:12:::1;::::0;:45:::1;::::0;-1:-1:-1;;;;;185996:12:0;;::::1;::::0;-1:-1:-1;;;;;185996:45:0;::::1;:25;:45::i;:::-;186067:46;::::0;-1:-1:-1;;;;;7834:47:1;;7816:66;;186097:7:0;;186085:10:::1;::::0;186067:46:::1;::::0;7804:2:1;7789:18;186067:46:0::1;;;;;;;185602:519;;143081:20:::0;142298:1;143601:7;:22;143418:213;102417:120;102480:7;102507:22;102521:7;102507:13;:22::i;102084:271::-;102147:7;102167:23;102193:19;:17;:19::i;:::-;102167:45;-1:-1:-1;;;;;;102227:19:0;;102223:89;;102297:1;102270:30;;-1:-1:-1;;;102270:30:0;;;;;;;;:::i;102223:89::-;-1:-1:-1;;;;;102329:18:0;;;;;;;:11;;;;:18;;-1:-1:-1;102329:18:0;;;;;102084:271::o;150262:103::-;149413:13;:11;:13::i;:::-;150327:30:::1;150354:1;150327:18;:30::i;:::-;150262:103::o:0;156347:280::-;149413:13;:11;:13::i;:::-;-1:-1:-1;;;;;156427:26:0;::::1;156423:52;;156462:13;;-1:-1:-1::0;;;156462:13:0::1;;;;;;;;;;;156423:52;156498:12;::::0;-1:-1:-1;;;;;156498:12:0::1;156490:35:::0;156486:74:::1;;156527:33;::::0;-1:-1:-1;;;156527:33:0;;17572:2:1;156527:33:0::1;::::0;::::1;17554:21:1::0;17611:2;17591:18;;;17584:30;-1:-1:-1;;;17630:18:1;;;17623:53;17693:18;;156527:33:0::1;17370:347:1::0;156486:74:0::1;156571:12;:48:::0;;-1:-1:-1;;;;;;156571:48:0::1;-1:-1:-1::0;;;;;156571:48:0;;;::::1;::::0;;;::::1;::::0;;156347:280::o;160222:1073::-;160290:7;160337:15;;;:6;:15;;;;;;;;160310:42;;;;;;;;;-1:-1:-1;;;;;160310:42:0;;;;;-1:-1:-1;;;160310:42:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;160310:42:0;;;;;;;;;160374:15;160367:39;;160363:67;;-1:-1:-1;153322:4:0;;160222:1073;-1:-1:-1;;160222:1073:0:o;160363:67::-;160537:15;160577;160555:4;:12;;;:38;;;;:::i;:::-;160537:56;-1:-1:-1;160764:17:0;153164:8;160785:29;153370:4;160784:41;160785:17;;:29;:::i;:::-;160784:41;;;;:::i;:::-;160764:61;-1:-1:-1;160932:22:0;153370:4;160764:61;160984:32;153370:4;153268;160984:32;:::i;:::-;-1:-1:-1;;;;;160976:41:0;:53;;;;:::i;:::-;160975:67;;;;:::i;:::-;160957:85;;153322:4;160957:85;:::i;:::-;160932:110;-1:-1:-1;160932:110:0;153268:4;-1:-1:-1;;;;;161132:27:0;;;161128:54;;;-1:-1:-1;153268:4:0;;160222:1073;-1:-1:-1;;;;;;160222:1073:0:o;161128:54::-;153322:4;-1:-1:-1;;;;;161197:28:0;;;161193:56;;;-1:-1:-1;153322:4:0;;160222:1073;-1:-1:-1;;;;;;160222:1073:0:o;161193:56::-;161277:10;160222:1073;-1:-1:-1;;;;;;160222:1073:0:o;149527:147::-;148358:22;149658:8;-1:-1:-1;;;;;149658:8:0;;149527:147::o;102822:153::-;102869:13;102895:23;102921:19;:17;:19::i;:::-;102895:45;;102958:1;:9;;102951:16;;;;;:::i;179559:199::-;179686:5;;;;;;179628:7;179673:19;;;:12;:19;;;;;;;;179648:44;;;;;;;;;;;;;;;-1:-1:-1;;;179648:44:0;;;;;;;;;;;;179686:5;179648:44;;;;;;;;;;;;-1:-1:-1;;;179648:44:0;;;;;;;;;179628:7;179718:31;179648:44;179739:9;179718;:31::i;:::-;179703:47;179559:199;-1:-1:-1;;;179559:199:0:o;104122:146::-;104208:52;25439:10;104241:8;104251;104208:18;:52::i;167433:226::-;167557:35;167578:4;167584:7;167557:20;:35::i;:::-;167604:47;167627:4;167633:2;167637:7;167646:4;167604:22;:47::i;180420:2466::-;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;180557:8:::2;156727;156709:15;:26;156705:56;;;156744:17;;-1:-1:-1::0;;;156744:17:0::2;;;;;;;;;;;156705:56;180600:1:::3;180582:19:::0;::::3;180578:47;;;180610:15;;-1:-1:-1::0;;;180610:15:0::3;;;;;;;;;;;180578:47;180646:19;::::0;;180781:376:::3;180801:19:::0;;::::3;180781:376;;;180870:10;180846:20;180854:8:::0;;180863:1;180854:11;;::::3;;;;;:::i;:::-;;;;;;;180846:7;:20::i;:::-;-1:-1:-1::0;;;;;180846:34:0::3;;180842:62;;180889:15;;-1:-1:-1::0;;;180889:15:0::3;;;;;;;;;;;180842:62;180933:24;180960:6;:19;180967:8;;180976:1;180967:11;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;::::3;;180960:19:::0;;-1:-1:-1;180960:19:0;;::::3;::::0;;;;;;;;-1:-1:-1;180960:19:0;180933:46;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;180933:46:0;;::::3;::::0;;;-1:-1:-1;;;180933:46:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;180933:46:0;::::3;::::0;;::::3;::::0;;;;;-1:-1:-1;181008:26:0::3;::::0;;::::3;:::i;:::-;;;181068:13;181053:28;;:4;:12;;;:28;;;181049:97;;;181118:4;:12;;;181102:28;;181049:97;-1:-1:-1::0;180822:3:0::3;;180781:376;;;-1:-1:-1::0;181216:24:0::3;181243:39;181266:15;181243:13:::0;:39:::3;:::i;:::-;181216:66:::0;-1:-1:-1;153164:8:0::3;181297:27;::::0;::::3;;181293:57;;;181333:17;;-1:-1:-1::0;;;181333:17:0::3;;;;;;;;;;;181293:57;181426:16;153164:8;181454:32;153370:4;-1:-1:-1::0;;;;;181454:20:0;::::3;:32;:::i;:::-;181453:44;;;;:::i;:::-;181426:72;;181519:18;181542:12;;181540:14;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;181519:35;;;;181565:33;181575:10;181587;181565:9;:33::i;:::-;181673:9;181668:512;181688:19:::0;;::::3;181668:512;;;181729:15;181747:8;;181756:1;181747:11;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;::::3;;181773:27;181803:15:::0;;;:6:::3;:15:::0;;;;;;181773:45;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;181773:45:0;;::::3;::::0;;-1:-1:-1;;;181773:45:0;;::::3;;::::0;;::::3;::::0;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;-1:-1:-1;;;181773:45:0;;::::3;::::0;::::3;::::0;;;;181887:127;;;;::::3;::::0;;181943:14;;181887:127:::3;;::::0;;181983:15;;181887:127:::3;::::0;;::::3;::::0;182082:19;;;;::::3;::::0;;;;;;;;::::3;::::0;;;;181747:11;;-1:-1:-1;181773:45:0;181887:127;-1:-1:-1;182043:59:0::3;::::0;181747:11;;181887:127;;182043:11:::3;:59::i;:::-;182124:15;::::0;;;:6:::3;:15;::::0;;;;182117:22;;;;::::3;::::0;;-1:-1:-1;;;;;;182117:22:0;;;182154:14:::3;182131:7:::0;182154:5:::3;:14::i;:::-;-1:-1:-1::0;;;181709:3:0::3;;181668:512;;;-1:-1:-1::0;182251:110:0::3;::::0;;;;::::3;::::0;;::::3;::::0;;::::3;::::0;;::::3;::::0;::::3;;::::0;;::::3;::::0;;;;182406:19;;;;::::3;::::0;;;182220:28:::3;182406:19:::0;;;;;::::3;::::0;182251:110;182382:53:::3;::::0;182394:10;;182251:110;182382:11:::3;:53::i;:::-;182477:176;::::0;;::::3;::::0;::::3;::::0;;-1:-1:-1;;;;;182477:176:0;;::::3;::::0;;;;::::3;;::::0;;::::3;::::0;;;::::3;::::0;;::::3;::::0;;;;;;182595:15:::3;182477:176:::0;::::3;::::0;;;;;;-1:-1:-1;182456:18:0;;;:6:::3;:18:::0;;;;;:197;;;;;::::3;-1:-1:-1::0;;;182456:197:0::3;::::0;;;::::3;::::0;;;::::3;::::0;;;;;;::::3;::::0;;;;;::::3;-1:-1:-1::0;;;182456:197:0::3;-1:-1:-1::0;;;;;;182456:197:0;;;;;;::::3;::::0;;;;::::3;::::0;;;182741:10:::3;182726:26:::0;;;:14:::3;:26:::0;;;;;;;;;::::3;::::0;;::::3;:51:::0;;::::3;:55:::0;;::::3;182691:91:::0;;::::3;-1:-1:-1::0;;182691:91:0;;::::3;::::0;;;::::3;::::0;;;182819:59;;182463:10;;182741;-1:-1:-1;;;;;;;;;;;182819:59:0;::::3;::::0;182513:11;;182548:13;;-1:-1:-1;;;;;16901:47:1;;;;16883:66;;16997:10;16985:23;16980:2;16965:18;;16958:51;16871:2;16856:18;;16711:304;182819:59:0::3;;;;;;;;180567:2319;;;;;;145602:1:::2;143081:20:::0;142298:1;143601:7;:22;143418:213;178399:1152;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;178604:8:::2;156727;156709:15;:26;156705:56;;;156744:17;;-1:-1:-1::0;;;156744:17:0::2;;;;;;;;;;;156705:56;156833:24:::3;156860:15:::0;;;:6:::3;:15;::::0;;;;;;;;156833:42;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;156833:42:0;;::::3;::::0;;;-1:-1:-1;;;156833:42:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;156833:42:0;::::3;::::0;;::::3;::::0;;;;178619:7;;156833:42;156890:15;;;;:57:::3;;;156935:4;:12;;;156909:38;;156916:15;156909:38;;;156890:57;156886:3309;;;157047:15;157087;157065:4;:12;;;:38;;;;:::i;:::-;157047:56:::0;-1:-1:-1;157204:17:0::3;153164:8;157225:29;153370:4;157224:41;157225:17:::0;::::3;:29;:::i;:::-;157224:41;;;;:::i;:::-;157204:61:::0;-1:-1:-1;157280:22:0::3;153370:4;157204:61:::0;157332:32:::3;153370:4:::0;153268::::3;157332:32;:::i;:::-;-1:-1:-1::0;;;;;157324:41:0::3;:53;;;;:::i;:::-;157323:67;;;;:::i;:::-;157305:85;::::0;153322:4:::3;157305:85;:::i;:::-;157280:110:::0;-1:-1:-1;157280:110:0;153268:4:::3;-1:-1:-1::0;;;;;157485:30:0;::::3;;157481:66;;;-1:-1:-1::0;153268:4:0::3;157481:66;153322:4;-1:-1:-1::0;;;;;157566:31:0;::::3;;157562:68;;;-1:-1:-1::0;153322:4:0::3;157562:68;157762:11:::0;;157733:17:::3;::::0;153370:4:::3;::::0;157754:30:::3;::::0;153164:8:::3;::::0;-1:-1:-1;;;;;157754:20:0::3;:30;:::i;:::-;157753:44;;;;:::i;:::-;157733:64;;157812:16;157839:9;157812:37;;157985:8;-1:-1:-1::0;;;;;157971:22:0::3;:4;:10;;;-1:-1:-1::0;;;;;157971:22:0::3;;;:70;;;;158035:6;158016:4;:15;;;157998:33;;:15;:33;;;;:::i;:::-;157997:44;157971:70;157967:2217;;;158164:10;::::0;::::3;::::0;158120:21:::3;::::0;-1:-1:-1;;;;;158164:14:0::3;::::0;158160:591:::3;;158203:20;153164:8;158227:29;153370:4;158226:41;158227:17:::0;::::3;:29;:::i;:::-;158226:41;;;;:::i;:::-;158203:64:::0;-1:-1:-1;158290:25:0::3;153370:4;158203:64:::0;158345:32:::3;153370:4:::0;153268::::3;158345:32;:::i;:::-;-1:-1:-1::0;;;;;158337:41:0::3;:56;;;;:::i;:::-;158336:70;;;;:::i;:::-;158318:88;::::0;153322:4:::3;158318:88;:::i;:::-;158290:116:::0;-1:-1:-1;158290:116:0;;-1:-1:-1;153268:4:0::3;-1:-1:-1::0;;;;;158498:30:0;::::3;;158494:66;;;153268:4;158530:30;;158494:66;153322:4;-1:-1:-1::0;;;;;158587:31:0;::::3;;158583:68;;;153322:4;158620:31;;158583:68;158180:491;;158160:591;;;-1:-1:-1::0;153322:4:0::3;158160:591;158824:11:::0;;158787:25:::3;::::0;153370:4:::3;::::0;158816:36:::3;::::0;-1:-1:-1;;;;;158816:36:0;;::::3;::::0;:20:::3;:36;:::i;:::-;158815:50;;;;:::i;:::-;158921:11:::0;;158787:78;;-1:-1:-1;158884:25:0::3;::::0;153370:4:::3;::::0;158913:36:::3;::::0;-1:-1:-1;;;;;158913:36:0;;::::3;::::0;:20:::3;:36;:::i;:::-;158912:50;;;;:::i;:::-;158884:78;;159084:17;159064;:37;159060:617;;;159126:16;159145:37;159165:17:::0;159145;:37:::3;:::i;:::-;159205:20;:41:::0;;159126:56;;-1:-1:-1;159126:56:0;;159205:20:::3;::::0;:41:::3;::::0;159126:56;;-1:-1:-1;;;;;159205:41:0::3;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;159205:41:0::3;;;;;-1:-1:-1::0;;;;;159205:41:0::3;;;;;;159103:163;159060:617;;;159296:17;159276;:37;159272:405;;;159338:16;159357:37;159377:17:::0;159357;:37:::3;:::i;:::-;159432:20;::::0;159338:56;;-1:-1:-1;;;;;;159432:20:0::3;159421:31:::0;::::3;159417:241;;;159481:20;:24:::0;;-1:-1:-1;;;;;;159481:24:0::3;::::0;;159417:241:::3;;;159593:20;:41:::0;;159625:8;;159593:20;::::3;::::0;:41:::3;::::0;159625:8;;-1:-1:-1;;;;;159593:41:0::3;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;159593:41:0::3;;;;;-1:-1:-1::0;;;;;159593:41:0::3;;;;;;159417:241;159315:362;159272:405;159765:220;159799:7;159829:57;;;;;;;;159858:4;:11;;;159829:57;;;;;;159873:4;:12;;;159829:57;;;;::::0;159909::::3;;;;;;;;159938:4;:11;;;159909:57;;;;;;159953:4;:12;;;159909:57;;;;::::0;159765:11:::3;:220::i;:::-;-1:-1:-1::0;;;160065:15:0::3;::::0;;;:6:::3;:15;::::0;;;;:32;;-1:-1:-1;;;;;160065:32:0;;::::3;-1:-1:-1::0;;;160065:32:0::3;::::0;::::3;;::::0;;-1:-1:-1;160116:26:0::3;:52:::0;;::::3;160152:15;160116:52;-1:-1:-1::0;;;160116:52:0::3;-1:-1:-1::0;;160116:52:0;;::::3;;::::0;;157967:2217:::3;156949:3246;;;;;;156886:3309;178693:9:::4;178673:16;178681:7:::0;178673::::4;:16::i;:::-;-1:-1:-1::0;;;;;178673:29:0::4;;178669:106;;178739:10;178719:16;178727:7:::0;178719::::4;:16::i;:::-;-1:-1:-1::0;;;;;178719:30:0::4;;178715:58;;178758:15;;-1:-1:-1::0;;;178758:15:0::4;;;;;;;;;;;178715:58;178789:16;-1:-1:-1::0;;;;;178789:21:0::4;178809:1;178789:21:::0;178785:49:::4;;178819:15;;-1:-1:-1::0;;;178819:15:0::4;;;;;;;;;;;178785:49;178904:25;178932:15:::0;;;:6:::4;:15;::::0;;;;178962:11;;178932:15;;-1:-1:-1;;;;;178962:11:0;;::::4;:16:::0;;178958:44:::4;;178987:15;;-1:-1:-1::0;;;178987:15:0::4;;;;;;;;;;;178958:44;179044:12;::::0;::::4;::::0;::::4;::::0;;::::4;179024:15;179017:39:::0;;::::4;;179013:65;;179065:13;;-1:-1:-1::0;;;179065:13:0::4;;;;;;;;;;;179013:65;179151:12;::::0;:37:::4;::::0;-1:-1:-1;;;179151:37:0;;179127:21:::4;::::0;-1:-1:-1;;;;;179151:12:0::4;::::0;:22:::4;::::0;:37:::4;::::0;179182:4:::4;::::0;179151:37:::4;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;179199:12;::::0;179127:61;;-1:-1:-1;179199:74:0::4;::::0;-1:-1:-1;;;;;179199:12:0::4;179229:10;179249:4;-1:-1:-1::0;;;;;179199:74:0;::::4;:29;:74::i;:::-;179329:32;-1:-1:-1::0;;;;;179329:32:0;::::4;:13:::0;:32:::4;:::i;:::-;179288:12;::::0;:37:::4;::::0;-1:-1:-1;;;179288:37:0;;-1:-1:-1;;;;;179288:12:0;;::::4;::::0;:22:::4;::::0;:37:::4;::::0;179319:4:::4;::::0;179288:37:::4;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:73;179284:115;;179383:16;;-1:-1:-1::0;;;179383:16:0::4;;;;;;;;;;;179284:115;179481:62;179502:7;179511:16;179529:13;179481:20;:62::i;:::-;178628:923;;156822:3392:::3;156772:1;145602::::2;143081:20:::0;142298:1;143601:7;:22;143418:213;185356:172;149413:13;:11;:13::i;:::-;185417:14:::1;:21:::0;;-1:-1:-1;;;;185417:21:0::1;-1:-1:-1::0;;;185417:21:0::1;::::0;;185449:8:::1;:6;:8::i;:::-;185494:25;::::0;185473:47:::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;185494:25:0;;::::1;::::0;185473:47:::1;:::i;:::-;;;;;;;;185356:172::o:0;187405:495::-;187478:13;187533:1;187504:17;187513:7;187504:8;:17::i;:::-;-1:-1:-1;;;;;187504:31:0;;187500:60;;187544:16;;-1:-1:-1;;;187544:16:0;;;;;;;;;;;187500:60;187571:8;;-1:-1:-1;;;;;187571:8:0;187567:52;;187602:17;;-1:-1:-1;;;187602:17:0;;;;;;;;;;;187567:52;187712:8;;187742:53;;;;;8566:25:1;;;187677:12:0;;;;-1:-1:-1;;;;;187712:8:0;;;;8539:18:1;;187742:53:0;;;-1:-1:-1;;187742:53:0;;;;;;;;;;;;;;-1:-1:-1;;;;;187742:53:0;-1:-1:-1;;;187742:53:0;;;187712:90;;;187742:53;187712:90;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;187676:126;;;;187817:7;187809:41;;;;-1:-1:-1;;;187809:41:0;;18423:2:1;187809:41:0;;;18405:21:1;18462:2;18442:18;;;18435:30;-1:-1:-1;;;18481:18:1;;;18474:51;18542:18;;187809:41:0;18221:345:1;187809:41:0;187881:4;187870:26;;;;;;;;;;;;:::i;:::-;187863:33;187405:495;-1:-1:-1;;;;187405:495:0:o;184008:782::-;184093:7;184117:13;;;;;:35;;-1:-1:-1;153164:8:0;184134:18;;;;184117:35;184113:65;;;184161:17;;-1:-1:-1;;;184161:17:0;;;;;;;;;;;184113:65;184193:6;-1:-1:-1;;;;;184193:11:0;184203:1;184193:11;184189:39;;184213:15;;-1:-1:-1;;;184213:15:0;;;;;;;;;;;184189:39;184324:13;153370:4;184341:25;153164:8;-1:-1:-1;;;;;184341:15:0;;:25;:::i;:::-;184340:39;;;;:::i;:::-;184324:55;;184394:5;184403:1;184394:10;184390:38;;153322:4;184406:22;;;;;184390:38;184449:17;153164:8;184470:29;153370:4;184469:41;184470:17;;:29;:::i;:::-;184469:41;;;;:::i;:::-;184449:61;-1:-1:-1;184521:18:0;153370:4;184575:32;153370:4;153268;184575:32;:::i;:::-;184562:46;;-1:-1:-1;;;;;184562:46:0;:9;:46;:::i;:::-;184561:60;;;;:::i;:::-;184542:80;;153322:4;184542:80;:::i;:::-;184521:101;-1:-1:-1;153268:4:0;184650:27;;:132;;153322:4;184714:28;;:68;;184771:10;184650:132;;184714:68;153322:4;184650:132;;;153268:4;184643:139;184008:782;-1:-1:-1;;;;;;184008:782:0:o;182894:1106::-;182975:7;183014:23;;;:14;:23;;;;;;;;183052:14;;;183048:28;;183075:1;183068:8;;;;;183048:28;183097:24;183124:15;;;:6;:15;;;;;;;;;183097:42;;;;;;;;;-1:-1:-1;;;;;183097:42:0;;;;;;-1:-1:-1;;;183097:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;183097:42:0;;;;;;;;;183154:16;;:45;;;183187:4;:12;;;183174:25;;:9;:25;;;;183154:45;183150:59;;;183208:1;183201:8;;;;;;183150:59;183238:9;183222:752;183254:1;183249;:6;;;183222:752;;183277:18;183298:25;;;:16;:25;;;;;;;;:28;;;;;;;;;;;;;183277:49;;;;;;;;;;;;;;;-1:-1:-1;;;183277:49:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;183277:49:0;;;;;;;;;;183345:21;;-1:-1:-1;183341:622:0;;183416:12;;;;183387:17;;153164:8;;153370:4;;183416:24;;183431:9;;183416:24;:::i;:::-;183408:33;;:45;;;;:::i;:::-;183407:57;;;;:::i;:::-;183387:77;-1:-1:-1;183483:18:0;153370:4;183537:32;153370:4;153268;183537:32;:::i;:::-;183524:46;;-1:-1:-1;;;;;183524:46:0;:9;:46;:::i;:::-;183523:60;;;;:::i;:::-;183504:80;;153322:4;183504:80;:::i;:::-;183483:101;-1:-1:-1;153268:4:0;183616:27;;:135;;153322:4;183692:28;;:59;;183741:10;183616:135;;183692:59;153322:4;183616:135;;;153268:4;183616:135;183821:10;;183603:148;;-1:-1:-1;183788:13:0;;153370:4;;183805:41;;183603:148;;-1:-1:-1;;;;;183805:28:0;:41;:::i;:::-;183804:55;;;;:::i;:::-;183788:71;-1:-1:-1;;;;;;183885:25:0;;:62;;183941:5;183885:62;;;-1:-1:-1;;;;;183885:62:0;183878:69;;;;;;;;;;;183341:622;-1:-1:-1;183257:3:0;;;;:::i;:::-;;;;183222:752;;;-1:-1:-1;183991:1:0;;182894:1106;-1:-1:-1;;;;;182894:1106:0:o;185049:271::-;185189:15;;185133:7;;;;185189:15;-1:-1:-1;;;185189:15:0;;;;;185174:30;;;;:78;;185240:12;185174:78;;;185222:15;;185207:30;;-1:-1:-1;;;185222:15:0;;;;185207:12;:30;:::i;:::-;185153:99;;185270:42;185292:6;185300:11;185270:21;:42::i;171759:1800::-;171969:15;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;171950:8:::2;156727;156709:15;:26;156705:56;;;156744:17;;-1:-1:-1::0;;;156744:17:0::2;;;;;;;;;;;156705:56;172001:6:::3;-1:-1:-1::0;;;;;172001:11:0::3;172011:1;172001:11:::0;171997:39:::3;;172021:15;;-1:-1:-1::0;;;172021:15:0::3;;;;;;;;;;;171997:39;172051:17;::::0;::::3;::::0;;:43:::3;;-1:-1:-1::0;153164:8:0::3;172072:22;::::0;::::3;;172051:43;172047:73;;;172103:17;;-1:-1:-1::0;;;172103:17:0::3;;;;;;;;;;;172047:73;172150:10;172135:26;::::0;;;:14:::3;:26;::::0;;;;;153425:3:::3;172135:48;:26:::0;;::::3;:48;172131:78;;172192:17;;-1:-1:-1::0;;;172192:17:0::3;;;;;;;;;;;172131:78;172230:17;172250:38;172276:12:::0;172257:15:::3;172250:38;:::i;:::-;172230:58;;172310:13;172325:18;172347:61;172372:6;172380:12;172394:13;172347:24;:61::i;:::-;172309:99;;;;172465:28;172496:102;;;;;;;;172548:6;172496:102;;;;;;172576:10;172496:102;;;;::::0;172465:133:::3;;172665:44;172677:1;172680:19;;;;;;;;172694:1;172680:19;;;;;;172697:1;172680:19;;;;::::0;172701:7:::3;172665:11;:44::i;:::-;172798:12;::::0;:37:::3;::::0;-1:-1:-1;;;172798:37:0;;172774:21:::3;::::0;-1:-1:-1;;;;;172798:12:0::3;::::0;:22:::3;::::0;:37:::3;::::0;172829:4:::3;::::0;172798:37:::3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;172846:12;::::0;172774:61;;-1:-1:-1;172846:64:0::3;::::0;-1:-1:-1;;;;;172846:12:0::3;172876:10;172896:4;-1:-1:-1::0;;;;;172846:64:0;::::3;:29;:64::i;:::-;172966:22;-1:-1:-1::0;;;;;172966:22:0;::::3;:13:::0;:22:::3;:::i;:::-;172925:12;::::0;:37:::3;::::0;-1:-1:-1;;;172925:37:0;;-1:-1:-1;;;;;172925:12:0;;::::3;::::0;:22:::3;::::0;:37:::3;::::0;172956:4:::3;::::0;172925:37:::3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:63;172921:106;;173011:16;;-1:-1:-1::0;;;173011:16:0::3;;;;;;;;;;;172921:106;173083:12;:14:::0;;::::3;;-1:-1:-1::0;;;173083:14:0;;::::3;::::0;::::3;::::0;;::::3;::::0;;::::3;;-1:-1:-1::0;;;;173083:14:0;;::::3;::::0;;;::::3;::::0;;;173127:10:::3;-1:-1:-1::0;173112:26:0;;;:14:::3;:26;::::0;;;;:28;;::::3;::::0;;::::3;::::0;;::::3;::::0;;::::3;-1:-1:-1::0;;173112:28:0;;::::3;::::0;;;::::3;::::0;;;173083:14;-1:-1:-1;173172:30:0::3;::::0;173083:14;173172:9:::3;:30::i;:::-;173241:165;::::0;;::::3;::::0;::::3;::::0;;-1:-1:-1;;;;;173241:165:0;;::::3;::::0;;;;::::3;;::::0;;::::3;::::0;;;::::3;::::0;;::::3;::::0;;;;;;173351:15:::3;173241:165:::0;::::3;::::0;;;;;;-1:-1:-1;173223:15:0;;;:6:::3;:15:::0;;;;;;;:183;;;;;::::3;-1:-1:-1::0;;;173223:183:0::3;::::0;;;::::3;::::0;;;::::3;::::0;;;;;;::::3;::::0;;;;;::::3;-1:-1:-1::0;;;173223:183:0::3;-1:-1:-1::0;;;;;;173223:183:0;;;;;;::::3;::::0;;;;;;;::::3;::::0;;173427:50:::3;173230:7:::0;173277:6;173466:10;173427:21:::3;:50::i;:::-;173503:48;::::0;;-1:-1:-1;;;;;16901:47:1;;16883:66;;16997:10;16985:23;;16980:2;16965:18;;16958:51;173523:7:0;;173511:10:::3;::::0;-1:-1:-1;;;;;;;;;;;173503:48:0;16856:18:1;173503:48:0::3;;;;;;;171986:1573;;;;;145602:1:::2;143081:20:::0;142298:1;143601:7;:22;143418:213;104339;104427:4;104444:23;104470:19;:17;:19::i;:::-;-1:-1:-1;;;;;104507:27:0;;;;;;;:20;;;;;:27;;;;;;;;:37;;;;;;;;;;-1:-1:-1;;104507:37:0;;;;;104339:213::o;150520:220::-;149413:13;:11;:13::i;:::-;-1:-1:-1;;;;;150605:22:0;::::1;150601:93;;150679:1;150651:31;;-1:-1:-1::0;;;150651:31:0::1;;;;;;;;:::i;150601:93::-;150704:28;150723:8;150704:18;:28::i;186129:68::-:0;149413:13;:11;:13::i;:::-;186179:10:::1;:8;:10::i;100966:160::-:0;101087:21;;100966:160::o;117353:247::-;117416:7;117436:13;117452:17;117461:7;117452:8;:17::i;:::-;117436:33;-1:-1:-1;;;;;;117484:19:0;;117480:90;;117527:31;;-1:-1:-1;;;117527:31:0;;;;;8566:25:1;;;8539:18;;117527:31:0;8420:177:1;106540:187:0;106610:7;106630:23;106656:19;:17;:19::i;:::-;106693:26;;;;:17;;:26;;-1:-1:-1;;106693:26:0;;;;-1:-1:-1;;;;;106693:26:0;;106540:187::o;115469:122::-;115550:33;115559:2;115563:7;115572:4;115578;115550:8;:33::i;106244:175::-;106310:7;106330:23;106356:19;:17;:19::i;:::-;106393:18;;;;:9;;:18;;-1:-1:-1;;106393:18:0;;;;-1:-1:-1;;;;;106393:18:0;;106244:175::o;143117:293::-;142342:1;143251:7;;:19;143243:63;;;;-1:-1:-1;;;143243:63:0;;19655:2:1;143243:63:0;;;19637:21:1;19694:2;19674:18;;;19667:30;19733:33;19713:18;;;19706:61;19784:18;;143243:63:0;19453:355:1;143243:63:0;142342:1;143384:7;:18;143117:293::o;146126:108::-;146038:7;;;;146196:9;146188:38;;;;-1:-1:-1;;;146188:38:0;;20015:2:1;146188:38:0;;;19997:21:1;20054:2;20034:18;;;20027:30;-1:-1:-1;;;20073:18:1;;;20066:46;20129:18;;146188:38:0;19813:340:1;161303:363:0;161459:19;:17;:19::i;:::-;161503:12;;161499:160;;161532:115;161567:7;161594:9;161623;161532:16;:115::i;175339:380::-;175405:7;;175499:25;153164:8;-1:-1:-1;;;;;175499:15:0;;:25;:::i;:::-;175479:45;-1:-1:-1;175586:21:0;153370:4;175479:45;175586:21;:::i;:::-;175574:33;-1:-1:-1;;;;;;175626:30:0;;;175618:57;;;;-1:-1:-1;;;175618:57:0;;20360:2:1;175618:57:0;;;20342:21:1;20399:2;20379:18;;;20372:30;-1:-1:-1;;;20418:18:1;;;20411:44;20472:18;;175618:57:0;20158:338:1;175727:758:0;175812:7;175926:5;-1:-1:-1;;;;;175926:10:0;175935:1;175926:10;175922:38;;-1:-1:-1;153322:4:0;175938:22;;175922:38;176038:17;153164:8;176059:29;153370:4;176058:41;176059:17;;:29;:::i;:::-;176058:41;;;;:::i;:::-;176038:61;-1:-1:-1;176173:18:0;153370:4;176241:32;153370:4;153268;176241:32;:::i;:::-;176228:46;;-1:-1:-1;;;;;176228:46:0;:9;:46;:::i;:::-;176227:60;;;;:::i;:::-;176194:94;;153322:4;176194:94;:::i;:::-;176173:115;-1:-1:-1;153268:4:0;176313:27;;176309:54;;;153268:4;176342:21;;;;;;176309:54;153322:4;176378:28;;176374:56;;;153322:4;176408:22;;;;;;170077:1674;170360:24;170387:15;;;:6;:15;;;;;;;;170360:42;;;;;;;;;-1:-1:-1;;;;;170360:42:0;;;;;-1:-1:-1;;;170360:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;170360:42:0;;;;;;;;;;:24;170437:153;;153322:4;170437:153;;;170540:15;170518:4;:12;;;:38;;;;:::i;:::-;170495:62;;170503:4;:10;;;-1:-1:-1;;;;;170495:19:0;:62;;;;:::i;:::-;170476:82;;153322:4;170476:82;:::i;:::-;170413:177;-1:-1:-1;153268:4:0;-1:-1:-1;;;;;170619:30:0;;;170615:66;;;-1:-1:-1;153268:4:0;170615:66;153322:4;-1:-1:-1;;;;;170696:31:0;;;170692:68;;;-1:-1:-1;153322:4:0;170692:68;170832:25;153370:4;170861:40;-1:-1:-1;;;;;170879:22:0;;;;170861:15;;:40;:::i;:::-;170860:54;;;;:::i;:::-;170832:82;-1:-1:-1;170925:25:0;153370:4;170954:40;-1:-1:-1;;;;;170972:22:0;;;;170954:15;;:40;:::i;:::-;170953:54;;;;:::i;:::-;170925:82;;171119:17;171099;:37;171095:610;;;171153:16;171172:37;171192:17;171172;:37;:::i;:::-;171153:56;-1:-1:-1;;;;;;171228:28:0;;171224:58;;;171265:17;;-1:-1:-1;;;171265:17:0;;;;;;;;;;;171224:58;171297:20;:41;;171329:8;;171297:20;;;:41;;171329:8;;-1:-1:-1;;;;;171297:41:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;171297:41:0;;;;;-1:-1:-1;;;;;171297:41:0;;;;;;171138:212;171095:610;;;171380:17;171360;:37;171356:349;;;171414:16;171433:37;171453:17;171433;:37;:::i;:::-;171500:20;;171414:56;;-1:-1:-1;;;;;;171500:20:0;171489:31;;171485:209;;;171541:20;:24;;-1:-1:-1;;;;;;171541:24:0;;;171485:209;;;171637:20;:41;;171669:8;;171637:20;;;:41;;171669:8;;-1:-1:-1;;;;;171637:41:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;171637:41:0;;;;;-1:-1:-1;;;;;171637:41:0;;;;;;171485:209;171399:306;171356:349;170173:1578;;;;170077:1674;;;:::o;143418:213::-;142298:1;143601:7;:22;143418:213::o;101250:151::-;22576:20;:18;:20::i;:::-;101354:39:::1;101378:5;101385:7;101354:23;:39::i;142384:113::-:0;22576:20;:18;:20::i;:::-;142455:34:::1;:32;:34::i;145137:99::-:0;22576:20;:18;:20::i;:::-;145201:27:::1;:25;:27::i;148911:129::-:0;22576:20;:18;:20::i;:::-;148994:38:::1;149019:12;148994:24;:38::i;146563:118::-:0;145572:19;:17;:19::i;:::-;146623:7:::1;:14:::0;;-1:-1:-1;;146623:14:0::1;146633:4;146623:14;::::0;;146653:20:::1;146660:12;25439:10:::0;;25359:98;146660:12:::1;146653:20;;;;;;:::i;166878:347::-:0;-1:-1:-1;;;;;166998:18:0;;;;;;:57;;-1:-1:-1;167028:12:0;;-1:-1:-1;;;;;167028:12:0;167020:35;;166998:57;:92;;;;-1:-1:-1;167088:1:0;167059:17;167068:7;167059:8;:17::i;:::-;-1:-1:-1;;;;;167059:31:0;;;166998:92;166994:224;;;167111:12;;:28;;-1:-1:-1;;;167111:28:0;;;;;8566:25:1;;;167142:1:0;;-1:-1:-1;;;;;167111:12:0;;:19;;8539:18:1;;167111:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:32;167107:100;;;167164:12;;:27;;-1:-1:-1;;;167164:27:0;;;;;8566:25:1;;;-1:-1:-1;;;;;167164:12:0;;;;:18;;8539::1;;167164:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;104619:588::-;-1:-1:-1;;;;;104714:16:0;;104710:89;;104784:1;104754:33;;-1:-1:-1;;;104754:33:0;;;;;;;;:::i;104710:89::-;105020:21;105044:34;105052:2;105056:7;25439:10;105044:7;:34::i;:::-;105020:58;;105110:4;-1:-1:-1;;;;;105093:21:0;:13;-1:-1:-1;;;;;105093:21:0;;105089:111;;105138:50;;-1:-1:-1;;;105138:50:0;;-1:-1:-1;;;;;20721:32:1;;;105138:50:0;;;20703:51:1;20770:18;;;20763:34;;;20833:32;;20813:18;;;20806:60;20676:18;;105138:50:0;20501:371:1;169166:748:0;169317:13;;;169437:25;153164:8;-1:-1:-1;;;;;169437:15:0;;:25;:::i;:::-;169417:45;-1:-1:-1;169524:21:0;153370:4;169417:45;169524:21;:::i;:::-;169512:33;-1:-1:-1;;;;;;169564:30:0;;;169556:57;;;;-1:-1:-1;;;169556:57:0;;21079:2:1;169556:57:0;;;21061:21:1;21118:2;21098:18;;;21091:30;-1:-1:-1;;;21137:18:1;;;21130:44;21191:18;;169556:57:0;20877:338:1;169556:57:0;169640:9;169624:26;;169717:41;169738:5;169745:12;169717:20;:41::i;:::-;169704:54;-1:-1:-1;153268:4:0;-1:-1:-1;;;;;169783:27:0;;;169779:59;;;169819:19;;-1:-1:-1;;;169819:19:0;;;;;;;;;;;169779:59;169866:13;-1:-1:-1;;;;;169853:26:0;:10;-1:-1:-1;;;;;169853:26:0;;169849:57;;;169888:18;;-1:-1:-1;;;169888:18:0;;;;;;;;;;;169849:57;169352:562;169166:748;;;;;;:::o;134838:216::-;134977:68;;-1:-1:-1;;;;;21440:32:1;;;134977:68:0;;;21422:51:1;21509:32;;21489:18;;;21482:60;21558:18;;;21551:34;;;134950:96:0;;134970:5;;-1:-1:-1;;;135000:27:0;21395:18:1;;134977:68:0;;;;-1:-1:-1;;134977:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;134977:68:0;-1:-1:-1;;;;;;134977:68:0;;;;;;;;;;134950:19;:96::i;111537:102::-;111605:26;111615:2;111619:7;111605:26;;;;;;;;;;;;:9;:26::i;134405:188::-;134526:58;;-1:-1:-1;;;;;21788:32:1;;134526:58:0;;;21770:51:1;21837:18;;;21830:34;;;134499:86:0;;134519:5;;-1:-1:-1;;;134549:23:0;21743:18:1;;134526:58:0;21596:274:1;112415:232:0;112467:21;112491:40;112507:1;112511:7;112528:1;112491:7;:40::i;:::-;112467:64;-1:-1:-1;;;;;;112546:27:0;;112542:98;;112597:31;;-1:-1:-1;;;112597:31:0;;;;;8566:25:1;;;8539:18;;112597:31:0;8420:177:1;149752:166:0;25439:10;149812:7;:5;:7::i;:::-;-1:-1:-1;;;;;149812:23:0;;149808:103;;25439:10;149859:40;;-1:-1:-1;;;149859:40:0;;;;;;;;:::i;150900:253::-;148358:22;151051:8;;-1:-1:-1;;;;;;151070:19:0;;-1:-1:-1;;;;;151070:19:0;;;;;;;;151105:40;;151051:8;;;;;151105:40;;150974:24;;151105:40;150963:190;;150900:253;:::o;179766:646::-;179838:7;179858:9;153210;;179871:5;:8;;;:15;;;;:::i;:::-;179870:24;;;;:::i;:::-;179858:36;-1:-1:-1;179920:9:0;179915:388;179939:3;179935:1;:7;179915:388;;;179960:10;153210:9;179960:10;;:::i;:::-;;;179994:1;179989:6;;:2;:6;;;179985:128;;;180063:8;;;;180059:12;;:1;:12;:::i;:::-;180051:21;;180030:5;:11;;;:43;;;;:::i;:::-;180016:57;;:5;;:57;;;;;:::i;:::-;;;;;-1:-1:-1;180092:5:0;;179985:128;180175:8;;;;180170:13;;:2;:13;:::i;:::-;180162:22;;180141:5;:11;;;:44;;;;:::i;:::-;180127:58;;:5;;:58;;;;;:::i;:::-;;;;;;;;180215:16;;;;;;;:12;:16;;;;;;;;;180200:11;;;:31;;180215:16;;;;;-1:-1:-1;180200:31:0;;180215:16;;180200:31;:::i;:::-;;;;;-1:-1:-1;180246:13:0;;;:8;;;:13;180286:3;;179915:388;;;;180332:1;180319:5;:10;;;:14;;;180315:34;;;180348:1;180335:14;;180315:34;-1:-1:-1;;180391:10:0;;-1:-1:-1;;;;;180375:28:0;;179766:646;-1:-1:-1;179766:646:0:o;116734:376::-;116838:23;116864:19;:17;:19::i;:::-;116838:45;-1:-1:-1;;;;;;116898:22:0;;116894:93;;116966:8;116944:31;;-1:-1:-1;;;116944:31:0;;;;;;;;:::i;116894:93::-;-1:-1:-1;;;;;116997:27:0;;;;;;;:20;;;:27;;;;;;;;:37;;;;;;;;;;;;;:48;;-1:-1:-1;;116997:48:0;;;;;;;;;;117061:41;;540::1;;;117061::0;;513:18:1;117061:41:0;;;;;;;116827:283;116734:376;;;:::o;105483:236::-;105597:31;105610:4;105616:2;105620:7;105597:12;:31::i;:::-;105639:72;25439:10;105687:4;105693:2;105697:7;105706:4;105639:33;:72::i;176550:1841::-;176699:25;176727:15;;;:6;:15;;;;;176835:11;;176727:15;;-1:-1:-1;;;;;176835:11:0;;;;176877:28;176889:16;176835:11;176877:28;:::i;:::-;176933:12;;;;176857:48;;-1:-1:-1;176933:12:0;;176916:14;176983:33;177000:15;176933:12;176983:33;:::i;:::-;176956:60;;177084:16;177103:29;177122:9;177103:18;:29::i;:::-;177084:48;;177143:18;177164:49;177185:8;177195:17;177164:20;:49::i;:::-;177143:70;;177290:25;177318:29;177339:7;177318:20;:29::i;:::-;177290:57;;177384:17;-1:-1:-1;;;;;177371:30:0;:10;-1:-1:-1;;;;;177371:30:0;;:63;;177417:17;177371:63;;;177404:10;177371:63;177358:76;-1:-1:-1;177526:16:0;177538:4;153370;177526:16;:::i;:::-;-1:-1:-1;;;;;177507:35:0;:16;-1:-1:-1;;;;;177507:35:0;;:65;;;;;177559:13;-1:-1:-1;;;;;177546:26:0;:10;-1:-1:-1;;;;;177546:26:0;;177507:65;177503:123;;;177596:18;;-1:-1:-1;;;177596:18:0;;;;;;;;;;;177503:123;177704:302;177730:7;177752:114;;;;;;;;177808:9;177752:114;;;;;;177843:7;177752:114;;;;;177881;;;;;;;;177937:9;177881:114;;;;;;177972:7;177881:114;;;;;177704:11;:302::i;:::-;-1:-1:-1;;;;;178091:21:0;;;-1:-1:-1;;;178091:21:0;178057:23;;;178091:21;;;178057:23;178123:15;;:41;;;178148:15;178123:41;-1:-1:-1;;;178123:41:0;-1:-1:-1;;178123:41:0;;;;;;178220:60;178242:7;178251:16;178269:10;178220:21;:60::i;:::-;178306:77;;;-1:-1:-1;;;;;23023:47:1;;;23005:66;;23107:47;;;23102:2;23087:18;;23080:75;23191:47;;23171:18;;;23164:75;178306:77:0;;178334:7;;178322:10;;178306:77;;;;;22993:2:1;178306:77:0;;;176688:1703;;;;;;;;176550:1841;;;:::o;146822:120::-;145831:16;:14;:16::i;:::-;146881:7:::1;:15:::0;;-1:-1:-1;;146881:15:0::1;::::0;;146912:22:::1;25439:10:::0;146921:12:::1;25359:98:::0;115779:736;115884:23;115910:19;:17;:19::i;:::-;115884:45;;115997:9;:31;;;-1:-1:-1;;;;;;116010:18:0;;;;115997:31;115993:471;;;116045:13;116061:22;116075:7;116061:13;:22::i;:::-;116045:38;-1:-1:-1;;;;;;116214:18:0;;;;;;:35;;;116245:4;-1:-1:-1;;;;;116236:13:0;:5;-1:-1:-1;;;;;116236:13:0;;;116214:35;:69;;;;;116254:29;116271:5;116278:4;116254:16;:29::i;:::-;116253:30;116214:69;116210:144;;;116333:4;116311:27;;-1:-1:-1;;;116311:27:0;;;;;;;;:::i;116210:144::-;116374:9;116370:83;;;116429:7;116425:2;-1:-1:-1;;;;;116409:28:0;116418:5;-1:-1:-1;;;;;116409:28:0;;;;;;;;;;;116370:83;116030:434;115993:471;116476:26;;;;:17;;:26;;-1:-1:-1;;116476:26:0;;;:31;;-1:-1:-1;;;;;;116476:31:0;-1:-1:-1;;;;;116476:31:0;;;;;;;;;;115779:736::o;161674:1236::-;161739:5;;;;161755:22;;:::i;:::-;161833:10;;;;161829:289;;161872:12;:24;161885:10;161894:1;161885:6;:10;:::i;:::-;161872:24;;;;;;;;;;;;;;;;;;-1:-1:-1;161872:24:0;161860:36;;;;;;;;;;;;;;;-1:-1:-1;;;161860:36:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;161860:36:0;;;;;;;;;-1:-1:-1;161829:289:0;;;-1:-1:-1;161941:165:0;;;;;;;;-1:-1:-1;161941:165:0;;;;;;;;162030:15;161941:165;;;;;;;;;162077:12;161941:165;;;;;;;161829:289;162154:12;;;;162130:21;162281:40;;;;162288:15;162281:40;;;;162277:198;;;162449:12;;;;162431:30;;;;:15;:30;:::i;:::-;162388:13;;;;162373:28;;;;:12;:28;:::i;:::-;162360:42;;153370:4;162360:42;:::i;:::-;162359:103;;;;:::i;:::-;162338:125;;162277:198;162538:135;162578:9;162602:14;162631:10;162656:6;162538:25;:135::i;:::-;162526:147;-1:-1:-1;162694:10:0;:6;162703:1;162694:10;:::i;:::-;162686:5;:18;;;;;;-1:-1:-1;;162686:18:0;;;;;;162715:20;;;162686:5;162715:20;;;:12;:20;;;;;;;;:32;;;;;;-1:-1:-1;;;;;162715:32:0;;;-1:-1:-1;;;162715:32:0;;;;;;;;;;;162686:18;162715:32;;;;;;;;;;;;-1:-1:-1;;;162715:32:0;-1:-1:-1;;;;;;162715:32:0;;;;;;;;;;;;;;;;;;;;;;;162838:18;162834:69;;;-1:-1:-1;;162890:1:0;162873:18;;-1:-1:-1;161674:1236:0:o;164006:650::-;164167:17;;:::i;:::-;164195;;:::i;:::-;164232:34;164250:9;164261:4;164232:17;:34::i;:::-;;164277;164295:9;164306:4;164277:17;:34::i;:::-;;164332:71;164358:9;164369;164380:4;:10;;;164392:4;:10;;;164332:25;:71::i;:::-;164416:16;164435:23;;;:14;:23;;;;;;:27;;:23;;;:27;:::i;:::-;164473:23;;;;:14;:23;;;;;;;;:35;;;;;;-1:-1:-1;;164473:35:0;;;;;;;;164536:15;164519:33;;:7;;;:33;;;164581:12;164563:31;;:8;;;:31;;;164605:25;;;:16;:25;;;;;:36;;;;;;;;:43;;;;;;;-1:-1:-1;;;;;164605:43:0;;;-1:-1:-1;;;164605:43:0;;;;;;;;;;164473:35;164605:43;;;;;;;;;;-1:-1:-1;;;164605:43:0;-1:-1:-1;;;;;;164605:43:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;;164006:650:0:o;22736:145::-;24569:21;24250:40;-1:-1:-1;;;24250:40:0;;;;22799:75;;22845:17;;-1:-1:-1;;;22845:17:0;;;;;;;;;;;101409:223;22576:20;:18;:20::i;:::-;101523:23:::1;101549:19;:17;:19::i;:::-;101523:45:::0;-1:-1:-1;101523:45:0;101579:15:::1;101589:5:::0;101523:45;101579:15:::1;:::i;:::-;-1:-1:-1::0;101605:9:0::1;::::0;::::1;:19;101617:7:::0;101605:9;:19:::1;:::i;142505:111::-:0;22576:20;:18;:20::i;145244:97::-;22576:20;:18;:20::i;:::-;145318:7:::1;:15:::0;;-1:-1:-1;;145318:15:0::1;::::0;;145244:97::o;149048:240::-;22576:20;:18;:20::i;109617:886::-;109703:7;109723:23;109749:19;:17;:19::i;:::-;109723:45;;109779:12;109794:17;109803:7;109794:8;:17::i;:::-;109779:32;-1:-1:-1;;;;;;109874:18:0;;;109870:88;;109909:37;109926:4;109932;109938:7;109909:16;:37::i;:::-;-1:-1:-1;;;;;110005:18:0;;;110001:265;;110123:48;110140:1;110144:7;110161:1;110165:5;110123:8;:48::i;:::-;-1:-1:-1;;;;;110217:17:0;;;;;;:11;;;:17;;;;;:22;;-1:-1:-1;;110217:22:0;;;110001:265;-1:-1:-1;;;;;110282:16:0;;;110278:113;;-1:-1:-1;;;;;110344:15:0;;;;;;:11;;;:15;;;;;:20;;110363:1;110344:20;;;110278:113;110403:18;;;;:9;;;:18;;;;;;:23;;-1:-1:-1;;;;;;110403:23:0;-1:-1:-1;;;;;110403:23:0;;;;;;;;;110444:27;;110403:18;;110444:27;;;;;;;110491:4;109617:886;-1:-1:-1;;;;;109617:886:0:o;138828:660::-;139263:23;139289:69;139317:4;139289:69;;;;;;;;;;;;;;;;;139297:5;-1:-1:-1;;;;;139289:27:0;;;:69;;;;;:::i;:::-;139263:95;;139377:10;:17;139398:1;139377:22;:56;;;;139414:10;139403:30;;;;;;;;;;;;:::i;:::-;139369:111;;;;-1:-1:-1;;;139369:111:0;;25826:2:1;139369:111:0;;;25808:21:1;25865:2;25845:18;;;25838:30;25904:34;25884:18;;;25877:62;-1:-1:-1;;;25955:18:1;;;25948:40;26005:19;;139369:111:0;25624:406:1;111866:210:0;111961:18;111967:2;111971:7;111961:5;:18::i;:::-;111990:78;25439:10;112046:1;112050:2;112054:7;112063:4;14632:948;-1:-1:-1;;;;;14819:14:0;;;:18;14815:758;;14858:67;;-1:-1:-1;;;14858:67:0;;-1:-1:-1;;;;;14858:36:0;;;;;:67;;14895:8;;14905:4;;14911:7;;14920:4;;14858:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14858:67:0;;;;;;;;-1:-1:-1;;14858:67:0;;;;;;;;;;;;:::i;:::-;;;14854:708;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15221:6;:13;15238:1;15221:18;15217:330;;15363:2;15327:39;;-1:-1:-1;;;15327:39:0;;;;;;;;:::i;15217:330::-;15497:6;15491:13;15482:6;15478:2;15474:15;15467:38;14854:708;-1:-1:-1;;;;;;14973:51:0;;-1:-1:-1;;;14973:51:0;14969:185;;15131:2;15095:39;;-1:-1:-1;;;15095:39:0;;;;;;;;:::i;14969:185::-;14926:243;14854:708;14632:948;;;;;:::o;146311:108::-;146038:7;;;;146370:41;;;;-1:-1:-1;;;146370:41:0;;26981:2:1;146370:41:0;;;26963:21:1;27020:2;27000:18;;;26993:30;-1:-1:-1;;;27039:18:1;;;27032:50;27099:18;;146370:41:0;26779:344:1;162918:1080:0;163096:12;;:::i;:::-;163121:9;153210;163134:21;153210:9;163134:14;:21;:::i;:::-;163133:30;;;;:::i;:::-;163121:42;-1:-1:-1;163192:15:0;163174:8;163229:735;163253:3;163249:1;:7;163229:735;;;163274:10;153210:9;163274:10;;:::i;:::-;;;163308:1;163303:6;;:2;:6;;;163299:232;;;163381:18;163385:14;163381:1;:18;:::i;:::-;163373:27;;163348:9;:15;;;:53;;;;:::i;:::-;163330:71;;:9;;:71;;;;;:::i;:::-;;;;;-1:-1:-1;163420:16:0;;;;:12;;;:16;163478:12;163455:36;:13;;;:36;163510:5;;163299:232;163596:19;163601:14;163596:2;:19;:::i;:::-;163588:28;;163563:9;:15;;;:54;;;;:::i;:::-;163545:72;;:9;;:72;;;;;:::i;:::-;;;;;;;;163651:16;;;;;;;:12;:16;;;;;;;;;163632:15;;;:35;;163651:16;;;;;-1:-1:-1;163632:35:0;;163651:16;;163632:35;:::i;:::-;;;;;-1:-1:-1;163682:17:0;;;:12;;;:17;;;153370:4;;163777:17;;163697:2;163777:17;:::i;:::-;163754:41;;;;-1:-1:-1;;;;;163754:19:0;;:41;:::i;:::-;163753:55;;;;:::i;:::-;163737:9;:13;;;:71;;;;;;:::i;:::-;163714:95;;:13;;;:95;:9;163838:12;:36;163871:1;163851:10;:6;163860:1;163851:10;:::i;:::-;:22;;;;:::i;:::-;163838:36;;;;;;;;;;;;;;;;;;-1:-1:-1;163838:36:0;:48;;;;;;-1:-1:-1;;;;;163838:48:0;;;-1:-1:-1;;;163838:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;163838:48:0;-1:-1:-1;;;;;;163838:48:0;;;;;;;;;;;;;;;163918:2;;-1:-1:-1;163918:2:0;;163947:3;163229:735;;;-1:-1:-1;163981:9:0;;162918:1080;-1:-1:-1;;;;;;162918:1080:0:o;164664:907::-;164788:4;164830:15;164809:37;;:6;:10;;;:37;;;;:59;;;-1:-1:-1;164850:13:0;;:18;;;164809:59;164805:77;;;-1:-1:-1;164877:5:0;164870:12;;164805:77;164903:16;164950:15;164930:6;:10;;;:36;;;;:::i;:::-;164922:45;;;-1:-1:-1;153164:8:0;164989:18;;:39;;165020:8;164989:39;;;153164:8;164989:39;164978:50;-1:-1:-1;165049:18:0;153164:8;165102:32;153322:4;153268;165102:32;:::i;:::-;165090:45;;-1:-1:-1;;;;;165090:45:0;:8;:45;:::i;:::-;165089:57;;;;:::i;:::-;165070:77;;153322:4;165070:77;:::i;:::-;165049:98;-1:-1:-1;153268:4:0;165171:27;;:127;;153322:4;165239:28;;:59;;165288:10;165171:127;;165239:59;153322:4;165171:127;;;153268:4;165171:127;165358:13;;165158:140;;-1:-1:-1;;;;;;165342:31:0;153370:4;165413:25;165158:140;165342:31;165413:25;:::i;:::-;165412:39;;;;:::i;:::-;165384:69;;;;153164:8;165494:24;153370:4;165494:12;:24;:::i;:::-;165493:36;;;;:::i;:::-;165464:67;;:11;;;:67;-1:-1:-1;165559:4:0;;-1:-1:-1;;;164664:907:0;;;;:::o;165579:1291::-;165844:15;165821:39;;:9;:13;;;:39;;;165817:579;;;165953:13;;;;;165940:27;;165921:16;165940:27;;;:12;:27;;;;;;;;;165982:21;165995:8;165940:27;165982:21;:::i;:::-;;;166191:9;:13;;;166174:30;;:9;:13;;;:30;;;166170:147;;166225:21;166238:8;166225:21;;:::i;:::-;;;166170:147;166358:13;;;;;166345:27;;;;;;:12;:27;;;;;;:39;;-1:-1:-1;;;;;;166345:39:0;-1:-1:-1;;;;;166345:39:0;;;;;;;;;;165817:579;166477:15;166454:39;;:9;:13;;;:39;;;166450:413;;;166530:9;:13;;;166514:29;;:9;:13;;;:29;;;166510:342;;;166675:13;;;;;166662:27;;166643:16;166662:27;;;:12;:27;;;;;;;;;166708:21;166721:8;166662:27;166708:21;:::i;:::-;166810:13;;;;;166797:27;;;;;;:12;:27;;;;;;:39;;-1:-1:-1;;;;;166797:39:0;;;-1:-1:-1;;;;;;166797:39:0;;;;;;;;;-1:-1:-1;165579:1291:0;;;;:::o;107766:376::-;107879:38;107893:5;107900:7;107909;107879:13;:38::i;:::-;107874:261;;-1:-1:-1;;;;;107938:19:0;;107934:190;;107985:31;;-1:-1:-1;;;107985:31:0;;;;;8566:25:1;;;8539:18;;107985:31:0;8420:177:1;107934:190:0;108064:44;;-1:-1:-1;;;108064:44:0;;-1:-1:-1;;;;;21788:32:1;;108064:44:0;;;21770:51:1;21837:18;;;21830:34;;;21743:18;;108064:44:0;21596:274:1;128228:229:0;128365:12;128397:52;128419:6;128427:4;128433:1;128436:12;128397:21;:52::i;110839:335::-;-1:-1:-1;;;;;110907:16:0;;110903:89;;110977:1;110947:33;;-1:-1:-1;;;110947:33:0;;;;;;;;:::i;110903:89::-;111002:21;111026:32;111034:2;111038:7;111055:1;111026:7;:32::i;:::-;111002:56;-1:-1:-1;;;;;;111073:27:0;;;111069:98;;111152:1;111124:31;;-1:-1:-1;;;111124:31:0;;;;;;;;:::i;107047:276::-;107150:4;-1:-1:-1;;;;;107187:21:0;;;;;;:128;;;107235:7;-1:-1:-1;;;;;107226:16:0;:5;-1:-1:-1;;;;;107226:16:0;;:52;;;;107246:32;107263:5;107270:7;107246:16;:32::i;:::-;107226:88;;;;107307:7;-1:-1:-1;;;;;107282:32:0;:21;107295:7;107282:12;:21::i;:::-;-1:-1:-1;;;;;107282:32:0;;;107047:276;-1:-1:-1;;;;107047:276:0:o;129314:455::-;129484:12;129542:5;129517:21;:30;;129509:81;;;;-1:-1:-1;;;129509:81:0;;27330:2:1;129509:81:0;;;27312:21:1;27369:2;27349:18;;;27342:30;27408:34;27388:18;;;27381:62;-1:-1:-1;;;27459:18:1;;;27452:36;27505:19;;129509:81:0;27128:402:1;129509:81:0;129602:12;129616:23;129643:6;-1:-1:-1;;;;;129643:11:0;129662:5;129669:4;129643:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129601:73;;;;129692:69;129719:6;129727:7;129736:10;129748:12;129692:26;:69::i;:::-;129685:76;129314:455;-1:-1:-1;;;;;;;129314:455:0:o;131887:644::-;132072:12;132101:7;132097:427;;;132129:10;:17;132150:1;132129:22;132125:290;;-1:-1:-1;;;;;125768:19:0;;;132339:60;;;;-1:-1:-1;;;132339:60:0;;27737:2:1;132339:60:0;;;27719:21:1;27776:2;27756:18;;;27749:30;27815:31;27795:18;;;27788:59;27864:18;;132339:60:0;27535:353:1;132339:60:0;-1:-1:-1;132436:10:0;132429:17;;132097:427;132479:33;132487:10;132499:12;133234:17;;:21;133230:388;;133466:10;133460:17;133523:15;133510:10;133506:2;133502:19;133495:44;133230:388;133593:12;133586:20;;-1:-1:-1;;;133586:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::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;592:289::-;634:3;672:5;666:12;699:6;694:3;687:19;755:6;748:4;741:5;737:16;730:4;725:3;721:14;715:47;807:1;800:4;791:6;786:3;782:16;778:27;771:38;870:4;863:2;859:7;854:2;846:6;842:15;838:29;833:3;829:39;825:50;818:57;;;592:289;;;;:::o;886:220::-;1035:2;1024:9;1017:21;998:4;1055:45;1096:2;1085:9;1081:18;1073:6;1055:45;:::i;1111:226::-;1170:6;1223:2;1211:9;1202:7;1198:23;1194:32;1191:52;;;1239:1;1236;1229:12;1191:52;-1:-1:-1;1284:23:1;;1111:226;-1:-1:-1;1111:226:1:o;1342:203::-;-1:-1:-1;;;;;1506:32:1;;;;1488:51;;1476:2;1461:18;;1342:203::o;1550:173::-;1618:20;;-1:-1:-1;;;;;1667:31:1;;1657:42;;1647:70;;1713:1;1710;1703:12;1647:70;1550:173;;;:::o;1728:300::-;1796:6;1804;1857:2;1845:9;1836:7;1832:23;1828:32;1825:52;;;1873:1;1870;1863:12;1825:52;1896:29;1915:9;1896:29;:::i;:::-;1886:39;1994:2;1979:18;;;;1966:32;;-1:-1:-1;;;1728:300:1:o;2267:186::-;2326:6;2379:2;2367:9;2358:7;2354:23;2350:32;2347:52;;;2395:1;2392;2385:12;2347:52;2418:29;2437:9;2418:29;:::i;2458:611::-;2648:2;2660:21;;;2730:13;;2633:18;;;2752:22;;;2600:4;;2831:15;;;2805:2;2790:18;;;2600:4;2874:169;2888:6;2885:1;2882:13;2874:169;;;2949:13;;2937:26;;2992:2;3018:15;;;;2983:12;;;;2910:1;2903:9;2874:169;;;-1:-1:-1;3060:3:1;;2458:611;-1:-1:-1;;;;;2458:611:1:o;3074:163::-;3141:20;;3201:10;3190:22;;3180:33;;3170:61;;3227:1;3224;3217:12;3242:298;3309:6;3317;3370:2;3358:9;3349:7;3345:23;3341:32;3338:52;;;3386:1;3383;3376:12;3338:52;3431:23;;;-1:-1:-1;3497:37:1;3530:2;3515:18;;3497:37;:::i;:::-;3487:47;;3242:298;;;;;:::o;3999:188::-;4067:20;;-1:-1:-1;;;;;4116:46:1;;4106:57;;4096:85;;4177:1;4174;4167:12;4192:493;4277:6;4285;4293;4301;4354:3;4342:9;4333:7;4329:23;4325:33;4322:53;;;4371:1;4368;4361:12;4322:53;4416:23;;;-1:-1:-1;4482:37:1;4515:2;4500:18;;4482:37;:::i;:::-;4472:47;-1:-1:-1;4592:2:1;4577:18;;4564:32;;-1:-1:-1;4641:38:1;4675:2;4660:18;;4641:38;:::i;:::-;4631:48;;4192:493;;;;;;;:::o;4690:127::-;4751:10;4746:3;4742:20;4739:1;4732:31;4782:4;4779:1;4772:15;4806:4;4803:1;4796:15;4822:275;4893:2;4887:9;4958:2;4939:13;;-1:-1:-1;;4935:27:1;4923:40;;-1:-1:-1;;;;;4978:34:1;;5014:22;;;4975:62;4972:88;;;5040:18;;:::i;:::-;5076:2;5069:22;4822:275;;-1:-1:-1;4822:275:1:o;5102:187::-;5151:4;-1:-1:-1;;;;;5176:6:1;5173:30;5170:56;;;5206:18;;:::i;:::-;-1:-1:-1;5272:2:1;5251:15;-1:-1:-1;;5247:29:1;5278:4;5243:40;;5102:187::o;5294:338::-;5359:5;5388:53;5404:36;5433:6;5404:36;:::i;:::-;5388:53;:::i;:::-;5379:62;;5464:6;5457:5;5450:21;5504:3;5495:6;5490:3;5486:16;5483:25;5480:45;;;5521:1;5518;5511:12;5480:45;5570:6;5565:3;5558:4;5551:5;5547:16;5534:43;5624:1;5617:4;5608:6;5601:5;5597:18;5593:29;5586:40;5294:338;;;;;:::o;5637:222::-;5680:5;5733:3;5726:4;5718:6;5714:17;5710:27;5700:55;;5751:1;5748;5741:12;5700:55;5773:80;5849:3;5840:6;5827:20;5820:4;5812:6;5808:17;5773:80;:::i;5864:687::-;5970:6;5978;5986;5994;6047:3;6035:9;6026:7;6022:23;6018:33;6015:53;;;6064:1;6061;6054:12;6015:53;6087:29;6106:9;6087:29;:::i;:::-;6077:39;;6135:38;6169:2;6158:9;6154:18;6135:38;:::i;:::-;6125:48;;6224:2;6213:9;6209:18;6196:32;-1:-1:-1;;;;;6243:6:1;6240:30;6237:50;;;6283:1;6280;6273:12;6237:50;6306;6348:7;6339:6;6328:9;6324:22;6306:50;:::i;:::-;6296:60;;;6409:2;6398:9;6394:18;6381:32;-1:-1:-1;;;;;6428:8:1;6425:32;6422:52;;;6470:1;6467;6460:12;6422:52;6493;6537:7;6526:8;6515:9;6511:24;6493:52;:::i;:::-;6483:62;;;5864:687;;;;;;;:::o;6556:374::-;6633:6;6641;6649;6702:2;6690:9;6681:7;6677:23;6673:32;6670:52;;;6718:1;6715;6708:12;6670:52;6741:29;6760:9;6741:29;:::i;:::-;6731:39;;6789:38;6823:2;6812:9;6808:18;6789:38;:::i;:::-;6556:374;;6779:48;;-1:-1:-1;;;6896:2:1;6881:18;;;;6868:32;;6556:374::o;6935:730::-;7030:6;7038;7046;7099:2;7087:9;7078:7;7074:23;7070:32;7067:52;;;7115:1;7112;7105:12;7067:52;7155:9;7142:23;-1:-1:-1;;;;;7180:6:1;7177:30;7174:50;;;7220:1;7217;7210:12;7174:50;7243:22;;7296:4;7288:13;;7284:27;-1:-1:-1;7274:55:1;;7325:1;7322;7315:12;7274:55;7365:2;7352:16;-1:-1:-1;;;;;7383:6:1;7380:30;7377:50;;;7423:1;7420;7413:12;7377:50;7478:7;7471:4;7461:6;7458:1;7454:14;7450:2;7446:23;7442:34;7439:47;7436:67;;;7499:1;7496;7489:12;7436:67;7530:4;7522:13;;;;7554:6;;-1:-1:-1;7614:20:1;;7601:34;;6935:730;-1:-1:-1;;;6935:730:1:o;7893:522::-;7987:6;7995;8003;8011;8019;8072:3;8060:9;8051:7;8047:23;8043:33;8040:53;;;8089:1;8086;8079:12;8040:53;8112:29;8131:9;8112:29;:::i;:::-;8102:39;;8160:38;8194:2;8183:9;8179:18;8160:38;:::i;:::-;8150:48;;8217:37;8250:2;8239:9;8235:18;8217:37;:::i;:::-;8207:47;-1:-1:-1;8323:2:1;8308:18;;8295:32;;-1:-1:-1;8370:39:1;8404:3;8389:19;;8370:39;:::i;:::-;8360:49;;7893:522;;;;;;;;:::o;8602:184::-;8660:6;8713:2;8701:9;8692:7;8688:23;8684:32;8681:52;;;8729:1;8726;8719:12;8681:52;8752:28;8770:9;8752:28;:::i;9881:118::-;9967:5;9960:13;9953:21;9946:5;9943:32;9933:60;;9989:1;9986;9979:12;10004:315;10069:6;10077;10130:2;10118:9;10109:7;10105:23;10101:32;10098:52;;;10146:1;10143;10136:12;10098:52;10169:29;10188:9;10169:29;:::i;:::-;10159:39;;10248:2;10237:9;10233:18;10220:32;10261:28;10283:5;10261:28;:::i;:::-;10308:5;10298:15;;;10004:315;;;;;:::o;10324:713::-;10419:6;10427;10435;10443;10496:3;10484:9;10475:7;10471:23;10467:33;10464:53;;;10513:1;10510;10503:12;10464:53;10536:29;10555:9;10536:29;:::i;:::-;10526:39;;10584:38;10618:2;10607:9;10603:18;10584:38;:::i;:::-;10574:48;-1:-1:-1;10691:2:1;10676:18;;10663:32;;-1:-1:-1;10770:2:1;10755:18;;10742:32;-1:-1:-1;;;;;10786:30:1;;10783:50;;;10829:1;10826;10819:12;10783:50;10852:22;;10905:4;10897:13;;10893:27;-1:-1:-1;10883:55:1;;10934:1;10931;10924:12;10883:55;10957:74;11023:7;11018:2;11005:16;11000:2;10996;10992:11;10957:74;:::i;11042:495::-;11128:6;11136;11144;11152;11205:3;11193:9;11184:7;11180:23;11176:33;11173:53;;;11222:1;11219;11212:12;11173:53;11267:23;;;-1:-1:-1;11333:38:1;11367:2;11352:18;;11333:38;:::i;11542:258::-;11609:6;11617;11670:2;11658:9;11649:7;11645:23;11641:32;11638:52;;;11686:1;11683;11676:12;11638:52;11709:29;11728:9;11709:29;:::i;:::-;11699:39;;11757:37;11790:2;11779:9;11775:18;11757:37;:::i;11805:447::-;11890:6;11898;11906;11914;11967:3;11955:9;11946:7;11942:23;11938:33;11935:53;;;11984:1;11981;11974:12;11935:53;12007:29;12026:9;12007:29;:::i;:::-;11997:39;;12055:37;12088:2;12077:9;12073:18;12055:37;:::i;12257:260::-;12325:6;12333;12386:2;12374:9;12365:7;12361:23;12357:32;12354:52;;;12402:1;12399;12392:12;12354:52;12425:29;12444:9;12425:29;:::i;:::-;12415:39;;12473:38;12507:2;12496:9;12492:18;12473:38;:::i;12522:380::-;12601:1;12597:12;;;;12644;;;12665:61;;12719:4;12711:6;12707:17;12697:27;;12665:61;12772:2;12764:6;12761:14;12741:18;12738:38;12735:161;;12818:10;12813:3;12809:20;12806:1;12799:31;12853:4;12850:1;12843:15;12881:4;12878:1;12871:15;12735:161;;12522:380;;;:::o;12907:127::-;12968:10;12963:3;12959:20;12956:1;12949:31;12999:4;12996:1;12989:15;13023:4;13020:1;13013:15;13039:127;13100:10;13095:3;13091:20;13088:1;13081:31;13131:4;13128:1;13121:15;13155:4;13152:1;13145:15;13171:135;13210:3;13231:17;;;13228:43;;13251:18;;:::i;:::-;-1:-1:-1;13298:1:1;13287:13;;13171:135::o;13311:170::-;13408:10;13401:18;;;13381;;;13377:43;;13432:20;;13429:46;;;13455:18;;:::i;13486:168::-;13559:9;;;13590;;13607:15;;;13601:22;;13587:37;13577:71;;13628:18;;:::i;13659:127::-;13720:10;13715:3;13711:20;13708:1;13701:31;13751:4;13748:1;13741:15;13775:4;13772:1;13765:15;13791:120;13831:1;13857;13847:35;;13862:18;;:::i;:::-;-1:-1:-1;13896:9:1;;13791:120::o;13916:243::-;-1:-1:-1;;;;;14031:42:1;;;13987;;;13983:91;;14086:44;;14083:70;;;14133:18;;:::i;14164:125::-;14229:9;;;14250:10;;;14247:36;;;14263:18;;:::i;14294:128::-;14361:9;;;14382:11;;;14379:37;;;14396:18;;:::i;14427:240::-;-1:-1:-1;;;;;14496:42:1;;;14540;;;14492:91;;14595:43;;14592:69;;;14641:18;;:::i;14672:167::-;14767:10;14740:18;;;14760;;;14736:43;;14791:19;;14788:45;;;14813:18;;:::i;15714:317::-;-1:-1:-1;;;;;15799:42:1;;;15843;;;15795:91;15906:52;;;;15977:24;;;15967:58;;16005:18;;:::i;:::-;15967:58;15714:317;;;;:::o;16036:227::-;16076:1;-1:-1:-1;;;;;16107:1:1;16103:42;16164:3;16154:37;;16171:18;;:::i;:::-;16253:3;-1:-1:-1;;;;;16213:1:1;16209:42;16205:52;16200:57;;;16036:227;;;;:::o;16268:249::-;16368:2;16357:17;;;16338;;;;16334:41;-1:-1:-1;;;;;;16390:50:1;;-1:-1:-1;;;;;16442:45:1;;16387:101;16384:127;;;16491:18;;:::i;16522:184::-;16592:6;16645:2;16633:9;16624:7;16620:23;16616:32;16613:52;;;16661:1;16658;16651:12;16613:52;-1:-1:-1;16684:16:1;;16522:184;-1:-1:-1;16522:184:1:o;17722:188::-;17760:3;17804:10;17797:5;17793:22;17839:10;17830:7;17827:23;17824:49;;17853:18;;:::i;:::-;17902:1;17889:15;;17722:188;-1:-1:-1;;17722:188:1:o;17915:301::-;18044:3;18082:6;18076:13;18128:6;18121:4;18113:6;18109:17;18104:3;18098:37;18190:1;18154:16;;18179:13;;;-1:-1:-1;18154:16:1;17915:301;-1:-1:-1;17915:301:1:o;18571:687::-;18651:6;18704:2;18692:9;18683:7;18679:23;18675:32;18672:52;;;18720:1;18717;18710:12;18672:52;18753:9;18747:16;-1:-1:-1;;;;;18778:6:1;18775:30;18772:50;;;18818:1;18815;18808:12;18772:50;18841:22;;18894:4;18886:13;;18882:27;-1:-1:-1;18872:55:1;;18923:1;18920;18913:12;18872:55;18956:2;18950:9;18981:53;18997:36;19026:6;18997:36;:::i;18981:53::-;19057:6;19050:5;19043:21;19105:7;19100:2;19091:6;19087:2;19083:15;19079:24;19076:37;19073:57;;;19126:1;19123;19116:12;19073:57;19174:6;19169:2;19165;19161:11;19156:2;19149:5;19145:14;19139:42;19226:1;19201:18;;;19221:2;19197:27;19190:38;;;;19205:5;18571:687;-1:-1:-1;;;;18571:687:1:o;19263:185::-;19301:3;19345:10;19338:5;19334:22;19375:7;19365:41;;19386:18;;:::i;:::-;-1:-1:-1;;19422:20:1;;19263:185;-1:-1:-1;;19263:185:1:o;21875:178::-;21914:1;21948:10;21945:1;21941:18;21978:3;21968:37;;21985:18;;:::i;:::-;22043:3;22030:10;22027:1;22023:18;22019:28;22014:33;;;21875:178;;;;:::o;22058:244::-;22169:10;22142:18;;;22162;;;22138:43;22201:28;;;;22248:24;;;22238:58;;22276:18;;:::i;22307:241::-;22346:7;22425:1;22421:2;22410:17;22406:1;22402:2;22391:17;22387:41;22463:11;22459:2;22448:27;22437:38;;22506:11;22497:7;22494:24;22484:58;;22522:18;;:::i;22553:245::-;22651:2;22621:17;;;22640;;;;22617:41;-1:-1:-1;;;;;22673:44:1;;-1:-1:-1;;;;;;22719:49:1;;22670:99;22667:125;;;22772:18;;:::i;23376:518::-;23478:2;23473:3;23470:11;23467:421;;;23514:5;23511:1;23504:16;23558:4;23555:1;23545:18;23628:2;23616:10;23612:19;23609:1;23605:27;23599:4;23595:38;23664:4;23652:10;23649:20;23646:47;;;-1:-1:-1;23687:4:1;23646:47;23742:2;23737:3;23733:12;23730:1;23726:20;23720:4;23716:31;23706:41;;23797:81;23815:2;23808:5;23805:13;23797:81;;;23874:1;23860:16;;23841:1;23830:13;23797:81;;24070:1299;24196:3;24190:10;-1:-1:-1;;;;;24215:6:1;24212:30;24209:56;;;24245:18;;:::i;:::-;24274:97;24364:6;24324:38;24356:4;24350:11;24324:38;:::i;:::-;24318:4;24274:97;:::i;:::-;24420:4;24451:2;24440:14;;24468:1;24463:649;;;;25156:1;25173:6;25170:89;;;-1:-1:-1;25225:19:1;;;25219:26;25170:89;-1:-1:-1;;24027:1:1;24023:11;;;24019:24;24015:29;24005:40;24051:1;24047:11;;;24002:57;25272:81;;24433:930;;24463:649;23323:1;23316:14;;;23360:4;23347:18;;-1:-1:-1;;24499:20:1;;;24617:222;24631:7;24628:1;24625:14;24617:222;;;24713:19;;;24707:26;24692:42;;24820:4;24805:20;;;;24773:1;24761:14;;;;24647:12;24617:222;;;24621:3;24867:6;24858:7;24855:19;24852:201;;;24928:19;;;24922:26;-1:-1:-1;;25011:1:1;25007:14;;;25023:3;25003:24;24999:37;24995:42;24980:58;24965:74;;24852:201;-1:-1:-1;;;;25099:1:1;25083:14;;;25079:22;25066:36;;-1:-1:-1;24070:1299:1:o;25374:245::-;25441:6;25494:2;25482:9;25473:7;25469:23;25465:32;25462:52;;;25510:1;25507;25500:12;25462:52;25542:9;25536:16;25561:28;25583:5;25561:28;:::i;26035:485::-;-1:-1:-1;;;;;26266:32:1;;;26248:51;;26335:32;;26330:2;26315:18;;26308:60;26399:2;26384:18;;26377:34;;;26447:3;26442:2;26427:18;;26420:31;;;-1:-1:-1;;26468:46:1;;26494:19;;26486:6;26468:46;:::i;26525:249::-;26594:6;26647:2;26635:9;26626:7;26622:23;26618:32;26615:52;;;26663:1;26660;26653:12;26615:52;26695:9;26689:16;26714:30;26738:5;26714:30;:::i
Swarm Source
ipfs://6c7cfd799d498e0dfe91275b4c271b021d906df60b72e04d91b2a212e82147b9
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.