Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TokenRun
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-06-16 */ // File: contracts/tokenrun/ERC721x/IERC721x.sol pragma solidity ^0.8.14; interface IERC721x { /** * @dev Returns if the token is locked (non-transferrable) or not. */ function isUnlocked(uint256 _id) external view returns (bool); /** * @dev Returns the amount of locks on the token. */ function lockCount(uint256 _tokenId) external view returns (uint256); /** * @dev Returns if a contract is allowed to lock/unlock tokens. */ function approvedContract(address _contract) external view returns (bool); /** * @dev Returns the contract that locked a token at a specific index in the mapping. */ function lockMap(uint256 _tokenId, uint256 _index) external view returns (address); /** * @dev Returns the mapping index of a contract that locked a token. */ function lockMapIndex(uint256 _tokenId, address _contract) external view returns (uint256); /** * @dev Locks a token, preventing it from being transferrable */ function lockId(uint256 _id) external; /** * @dev Unlocks a token. */ function unlockId(uint256 _id) external; /** * @dev Unlocks a token from a given contract if the contract is no longer approved. */ function freeId(uint256 _id, address _contract) external; } // File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * 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); } } } // File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```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 Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * 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 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } } // File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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; } /** * @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[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @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. * * By default, the owner account will be the one that deploys the contract. 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 { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @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) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @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; } // File: contracts/tokenrun/ERC721x/LockRegistry.sol pragma solidity ^0.8.14; abstract contract LockRegistry is OwnableUpgradeable, IERC721x { mapping(address => bool) public override approvedContract; mapping(uint256 => uint256) public override lockCount; mapping(uint256 => mapping(uint256 => address)) public override lockMap; mapping(uint256 => mapping(address => uint256)) public override lockMapIndex; event TokenLocked( uint256 indexed tokenId, address indexed approvedContract ); event TokenUnlocked( uint256 indexed tokenId, address indexed approvedContract ); function __LockRegistry_init() internal onlyInitializing { OwnableUpgradeable.__Ownable_init(); } function isUnlocked(uint256 _id) public view override returns (bool) { return lockCount[_id] == 0; } function updateApprovedContracts( address[] calldata _contracts, bool[] calldata _values ) external onlyOwner { require(_contracts.length == _values.length, "!length"); for (uint256 i = 0; i < _contracts.length; i++) approvedContract[_contracts[i]] = _values[i]; } function _lockId(uint256 _id) internal { require(approvedContract[msg.sender], "Cannot update map"); require( lockMapIndex[_id][msg.sender] == 0, "ID already locked by caller" ); uint256 count = lockCount[_id] + 1; lockMap[_id][count] = msg.sender; lockMapIndex[_id][msg.sender] = count; lockCount[_id]++; emit TokenLocked(_id, msg.sender); } function _unlockId(uint256 _id) internal { require(approvedContract[msg.sender], "Cannot update map"); uint256 index = lockMapIndex[_id][msg.sender]; require(index != 0, "ID not locked by caller"); uint256 last = lockCount[_id]; if (index != last) { address lastContract = lockMap[_id][last]; lockMap[_id][index] = lastContract; lockMap[_id][last] = address(0); lockMapIndex[_id][lastContract] = index; } else lockMap[_id][index] = address(0); lockMapIndex[_id][msg.sender] = 0; lockCount[_id]--; emit TokenUnlocked(_id, msg.sender); } function _freeId(uint256 _id, address _contract) internal { require(!approvedContract[_contract], "Cannot update map"); uint256 index = lockMapIndex[_id][_contract]; require(index != 0, "ID not locked"); uint256 last = lockCount[_id]; if (index != last) { address lastContract = lockMap[_id][last]; lockMap[_id][index] = lastContract; lockMap[_id][last] = address(0); lockMapIndex[_id][lastContract] = index; } else lockMap[_id][index] = address(0); lockMapIndex[_id][_contract] = 0; lockCount[_id]--; emit TokenUnlocked(_id, _contract); } } // File: erc721a-upgradeable/contracts/ERC721A__InitializableStorage.sol pragma solidity ^0.8.0; /** * @dev This is a base storage for the initialization function for upgradeable diamond facet contracts **/ library ERC721A__InitializableStorage { struct Layout { /* * Indicates that the contract has been initialized. */ bool _initialized; /* * Indicates that the contract is in the process of being initialized. */ bool _initializing; } bytes32 internal constant STORAGE_SLOT = keccak256('ERC721A.contracts.storage.initializable.facet'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } } // File: erc721a-upgradeable/contracts/ERC721A__Initializable.sol pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable diamond facet 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. * * 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. */ abstract contract ERC721A__Initializable { using ERC721A__InitializableStorage for ERC721A__InitializableStorage.Layout; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializerERC721A() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require( ERC721A__InitializableStorage.layout()._initializing ? _isConstructor() : !ERC721A__InitializableStorage.layout()._initialized, 'ERC721A__Initializable: contract is already initialized' ); bool isTopLevelCall = !ERC721A__InitializableStorage.layout()._initializing; if (isTopLevelCall) { ERC721A__InitializableStorage.layout()._initializing = true; ERC721A__InitializableStorage.layout()._initialized = true; } _; if (isTopLevelCall) { ERC721A__InitializableStorage.layout()._initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializingERC721A() { require( ERC721A__InitializableStorage.layout()._initializing, 'ERC721A__Initializable: contract is not initializing' ); _; } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; assembly { cs := extcodesize(self) } return cs == 0; } } // File: erc721a-upgradeable/contracts/ERC721AStorage.sol pragma solidity ^0.8.0; library ERC721AStorage { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } struct Layout { // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 _currentIndex; // The number of tokens burned. uint256 _burnCounter; // Token name string _name; // Token symbol string _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => ERC721AStorage.TokenApprovalRef) _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) _operatorApprovals; } bytes32 internal constant STORAGE_SLOT = keccak256('ERC721A.contracts.storage.ERC721A'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } } // File: erc721a-upgradeable/contracts/IERC721AUpgradeable.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721AUpgradeable { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @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`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be 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, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @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 payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @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); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: erc721a-upgradeable/contracts/ERC721AUpgradeable.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721ReceiverUpgradeable { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721AUpgradeable is ERC721A__Initializable, IERC721AUpgradeable { using ERC721AStorage for ERC721AStorage.Layout; // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // CONSTRUCTOR // ============================================================= function __ERC721A_init(string memory name_, string memory symbol_) internal onlyInitializingERC721A { __ERC721A_init_unchained(name_, symbol_); } function __ERC721A_init_unchained(string memory name_, string memory symbol_) internal onlyInitializingERC721A { ERC721AStorage.layout()._name = name_; ERC721AStorage.layout()._symbol = symbol_; ERC721AStorage.layout()._currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return ERC721AStorage.layout()._currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return ERC721AStorage.layout()._currentIndex - ERC721AStorage.layout()._burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return ERC721AStorage.layout()._currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return ERC721AStorage.layout()._burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return ERC721AStorage.layout()._packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (ERC721AStorage.layout()._packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (ERC721AStorage.layout()._packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(ERC721AStorage.layout()._packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = ERC721AStorage.layout()._packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); ERC721AStorage.layout()._packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return ERC721AStorage.layout()._name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return ERC721AStorage.layout()._symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @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, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(ERC721AStorage.layout()._packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (ERC721AStorage.layout()._packedOwnerships[index] == 0) { ERC721AStorage.layout()._packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) { if (_startTokenId() <= tokenId) { packed = ERC721AStorage.layout()._packedOwnerships[tokenId]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // If the data at the starting slot does not exist, start the scan. if (packed == 0) { if (tokenId >= ERC721AStorage.layout()._currentIndex) revert OwnerQueryForNonexistentToken(); // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `tokenId` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. for (;;) { unchecked { packed = ERC721AStorage.layout()._packedOwnerships[--tokenId]; } if (packed == 0) continue; return packed; } } // Otherwise, the data exists and is not burned. We can skip the scan. // This is possible because we have already achieved the target condition. // This saves 2143 gas on transfers of initialized tokens. return packed; } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}. * * Requirements: * * - The caller must own the token or be an approved operator. */ function approve(address to, uint256 tokenId) public payable virtual override { _approve(to, tokenId, true); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return ERC721AStorage.layout()._tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { ERC721AStorage.layout()._operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return ERC721AStorage.layout()._operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < ERC721AStorage.layout()._currentIndex && // If within bounds, ERC721AStorage.layout()._packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { ERC721AStorage.TokenApprovalRef storage tokenApproval = ERC721AStorage.layout()._tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --ERC721AStorage.layout()._packedAddressData[from]; // Updates: `balance -= 1`. ++ERC721AStorage.layout()._packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. ERC721AStorage.layout()._packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (ERC721AStorage.layout()._packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != ERC721AStorage.layout()._currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. ERC721AStorage.layout()._packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @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 memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721ReceiverUpgradeable(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (bytes4 retval) { return retval == ERC721A__IERC721ReceiverUpgradeable(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = ERC721AStorage.layout()._currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. ERC721AStorage.layout()._packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. ERC721AStorage.layout()._packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); ERC721AStorage.layout()._currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = ERC721AStorage.layout()._currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. ERC721AStorage.layout()._packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. ERC721AStorage.layout()._packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); ERC721AStorage.layout()._currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = ERC721AStorage.layout()._currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (ERC721AStorage.layout()._currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Equivalent to `_approve(to, tokenId, false)`. */ function _approve(address to, uint256 tokenId) internal virtual { _approve(to, tokenId, false); } /** * @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: * * - `tokenId` must exist. * * Emits an {Approval} event. */ function _approve( address to, uint256 tokenId, bool approvalCheck ) internal virtual { address owner = ownerOf(tokenId); if (approvalCheck) if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } ERC721AStorage.layout()._tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. ERC721AStorage.layout()._packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. ERC721AStorage.layout()._packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (ERC721AStorage.layout()._packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != ERC721AStorage.layout()._currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. ERC721AStorage.layout()._packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { ERC721AStorage.layout()._burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = ERC721AStorage.layout()._packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); ERC721AStorage.layout()._packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: contracts/tokenrun/ERC721x/ERC721x.sol pragma solidity ^0.8.14; contract ERC721x is Initializable, ERC721AUpgradeable, LockRegistry { /* * bytes4(keccak256('freeId(uint256,address)')) == 0x94d216d6 * bytes4(keccak256('isUnlocked(uint256)')) == 0x72abc8b7 * bytes4(keccak256('lockCount(uint256)')) == 0x650b00f6 * bytes4(keccak256('lockId(uint256)')) == 0x2799cde0 * bytes4(keccak256('lockMap(uint256,uint256)')) == 0x2cba8123 * bytes4(keccak256('lockMapIndex(uint256,address)')) == 0x09308e5d * bytes4(keccak256('unlockId(uint256)')) == 0x40a9c8df * bytes4(keccak256('approvedContract(address)')) == 0xb1a6505f * * => 0x94d216d6 ^ 0x72abc8b7 ^ 0x650b00f6 ^ 0x2799cde0 ^ * 0x2cba8123 ^ 0x09308e5d ^ 0x40a9c8df ^ 0xb1a6505f == 0x706e8489 */ bytes4 private constant _INTERFACE_ID_ERC721x = 0x706e8489; function __ERC721x_init(string memory _name, string memory _symbol) internal onlyInitializing { ERC721AUpgradeable.__ERC721A_init(_name, _symbol); LockRegistry.__LockRegistry_init(); } function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC721AUpgradeable) returns (bool) { return _interfaceId == _INTERFACE_ID_ERC721x || super.supportsInterface(_interfaceId); } function transferFrom( address _from, address _to, uint256 _tokenId ) public payable virtual override(ERC721AUpgradeable) { require(isUnlocked(_tokenId), "Token is locked"); ERC721AUpgradeable.transferFrom(_from, _to, _tokenId); } function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes memory _data ) public payable virtual override(ERC721AUpgradeable) { require(isUnlocked(_tokenId), "Token is locked"); ERC721AUpgradeable.safeTransferFrom(_from, _to, _tokenId, _data); } function lockId(uint256 _id) external virtual override { require(_exists(_id), "Token !exist"); _lockId(_id); } function unlockId(uint256 _id) external virtual override { require(_exists(_id), "Token !exist"); _unlockId(_id); } function freeId(uint256 _id, address _contract) external virtual override { require(_exists(_id), "Token !exist"); _freeId(_id, _contract); } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * 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 caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @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. * * By default, the owner account will be the one that deploys the contract. 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 Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @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) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing 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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/utils/StorageSlot.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * 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); } } } // File: @openzeppelin/contracts/interfaces/draft-IERC1822.sol // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); } // File: @openzeppelin/contracts/interfaces/IERC1967.sol // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); } // File: @openzeppelin/contracts/proxy/beacon/IBeacon.sol // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); } // File: @openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967Upgrade is IERC1967 { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } } // File: @openzeppelin/contracts/proxy/Proxy.sol // OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overridden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} } // File: @openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol // OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.0; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializing the storage of the proxy like a Solidity constructor. */ constructor(address _logic, bytes memory _data) payable { _upgradeToAndCall(_logic, _data, false); } /** * @dev Returns the current implementation address. */ function _implementation() internal view virtual override returns (address impl) { return ERC1967Upgrade._getImplementation(); } } // File: @openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol // OpenZeppelin Contracts (last updated v4.9.0) (proxy/transparent/TransparentUpgradeableProxy.sol) pragma solidity ^0.8.0; /** * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy} * does not implement this interface directly, and some of its functions are implemented by an internal dispatch * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not * include them in the ABI so this interface must be used to interact with it. */ interface ITransparentUpgradeableProxy is IERC1967 { function admin() external view returns (address); function implementation() external view returns (address); function changeAdmin(address) external; function upgradeTo(address) external; function upgradeToAndCall(address, bytes memory) external payable; } /** * @dev This contract implements a proxy that is upgradeable by an admin. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches one of the admin functions exposed by the proxy itself. * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the * implementation. If the admin tries to call a function on the implementation it will fail with an error that says * "admin cannot fallback to proxy target". * * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due * to sudden errors when trying to call a function from the proxy implementation. * * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. * * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not * inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the * implementation. * * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler * will not check that there are no selector conflicts, due to the note above. A selector clash between any new function * and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could * render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised. */ contract TransparentUpgradeableProxy is ERC1967Proxy { /** * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. */ constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) { _changeAdmin(admin_); } /** * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. * * CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the * implementation provides a function with the same selector. */ modifier ifAdmin() { if (msg.sender == _getAdmin()) { _; } else { _fallback(); } } /** * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior */ function _fallback() internal virtual override { if (msg.sender == _getAdmin()) { bytes memory ret; bytes4 selector = msg.sig; if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) { ret = _dispatchUpgradeTo(); } else if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) { ret = _dispatchUpgradeToAndCall(); } else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) { ret = _dispatchChangeAdmin(); } else if (selector == ITransparentUpgradeableProxy.admin.selector) { ret = _dispatchAdmin(); } else if (selector == ITransparentUpgradeableProxy.implementation.selector) { ret = _dispatchImplementation(); } else { revert("TransparentUpgradeableProxy: admin cannot fallback to proxy target"); } assembly { return(add(ret, 0x20), mload(ret)) } } else { super._fallback(); } } /** * @dev Returns the current admin. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function _dispatchAdmin() private returns (bytes memory) { _requireZeroValue(); address admin = _getAdmin(); return abi.encode(admin); } /** * @dev Returns the current implementation. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function _dispatchImplementation() private returns (bytes memory) { _requireZeroValue(); address implementation = _implementation(); return abi.encode(implementation); } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _dispatchChangeAdmin() private returns (bytes memory) { _requireZeroValue(); address newAdmin = abi.decode(msg.data[4:], (address)); _changeAdmin(newAdmin); return ""; } /** * @dev Upgrade the implementation of the proxy. */ function _dispatchUpgradeTo() private returns (bytes memory) { _requireZeroValue(); address newImplementation = abi.decode(msg.data[4:], (address)); _upgradeToAndCall(newImplementation, bytes(""), false); return ""; } /** * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the * proxied contract. */ function _dispatchUpgradeToAndCall() private returns (bytes memory) { (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes)); _upgradeToAndCall(newImplementation, data, true); return ""; } /** * @dev Returns the current admin. * * CAUTION: This function is deprecated. Use {ERC1967Upgrade-_getAdmin} instead. */ function _admin() internal view virtual returns (address) { return _getAdmin(); } /** * @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to * emulate some proxy functions being non-payable while still allowing value to pass through. */ function _requireZeroValue() private { require(msg.value == 0); } } // File: @openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol // OpenZeppelin Contracts (last updated v4.8.3) (proxy/transparent/ProxyAdmin.sol) pragma solidity ^0.8.0; /** * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}. */ contract ProxyAdmin is Ownable { /** * @dev Returns the current implementation of `proxy`. * * Requirements: * * - This contract must be the admin of `proxy`. */ function getProxyImplementation(ITransparentUpgradeableProxy proxy) public view virtual returns (address) { // We need to manually run the static call since the getter cannot be flagged as view // bytes4(keccak256("implementation()")) == 0x5c60da1b (bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b"); require(success); return abi.decode(returndata, (address)); } /** * @dev Returns the current admin of `proxy`. * * Requirements: * * - This contract must be the admin of `proxy`. */ function getProxyAdmin(ITransparentUpgradeableProxy proxy) public view virtual returns (address) { // We need to manually run the static call since the getter cannot be flagged as view // bytes4(keccak256("admin()")) == 0xf851a440 (bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440"); require(success); return abi.decode(returndata, (address)); } /** * @dev Changes the admin of `proxy` to `newAdmin`. * * Requirements: * * - This contract must be the current admin of `proxy`. */ function changeProxyAdmin(ITransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner { proxy.changeAdmin(newAdmin); } /** * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. * * Requirements: * * - This contract must be the admin of `proxy`. */ function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner { proxy.upgradeTo(implementation); } /** * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See * {TransparentUpgradeableProxy-upgradeToAndCall}. * * Requirements: * * - This contract must be the admin of `proxy`. */ function upgradeAndCall( ITransparentUpgradeableProxy proxy, address implementation, bytes memory data ) public payable virtual onlyOwner { proxy.upgradeToAndCall{value: msg.value}(implementation, data); } } // File: contracts/tokenrun/tokenrun.sol // pragma solidity ^0.8.18; pragma solidity ^0.8.18; contract TokenRun is ERC721x { string public prefixURI; uint256 public maxPerWallet; uint256 public mintPrice; bool enableTransfer; bool enableMint; mapping(address => uint256) public mintAddr; mapping(uint256 => address) public soulBonding; mapping(uint256 => uint256) public tokensLastStakedAt; event Stake(uint256 tokenId, address by, uint256 stakedAt); event Unstake( uint256 tokenId, address by, uint256 stakedAt, uint256 unstakedAt ); constructor() { // _disableInitializers(); } function initialize( string memory _prefixURI ) public initializerERC721A initializer { __ERC721x_init("TokenRun", "TATA"); prefixURI = _prefixURI; enableTransfer = true; enableMint = false; maxPerWallet = 1; mintPrice = 0; } function adminMint(address receiver, uint256 quantity) public onlyOwner { safeMint(receiver, quantity); } function mint() public payable { require(enableMint, "mint not enabled"); require(msg.value >= mintPrice, "insufficient value"); require(mintAddr[msg.sender] < maxPerWallet, "reached the maximum"); mintAddr[msg.sender] += 1; safeMint(msg.sender, 1); soulBonding[totalSupply()] = msg.sender; } function safeMint(address receiver, uint256 quantity) internal { _mint(receiver, quantity); } // // =============== URI =============== function _startTokenId() internal view virtual override returns (uint256) { return 1; } function _baseURI() internal view virtual override returns (string memory) { return prefixURI; } function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_exists(_tokenId), "TOKEN NOT EXIST"); return string.concat(super.tokenURI(_tokenId), ""); } function setBaseURI(string calldata _prefixURI) external onlyOwner { prefixURI = _prefixURI; } // // =============== Stake + MARKETPLACE CONTROL =============== function setMintPrice(uint256 _price) external onlyOwner { mintPrice = _price; } function setMintStatus(bool _enableMint) external onlyOwner { enableMint = _enableMint; } function setTransferStatus(bool _enableTransfer) external onlyOwner { enableTransfer = _enableTransfer; } function stake(uint256 tokenID) external { require(msg.sender == ownerOf(tokenID), "caller must be owner"); require(tokensLastStakedAt[tokenID] == 0, "already staking"); tokensLastStakedAt[tokenID] = block.timestamp; emit Stake(tokenID, msg.sender, tokensLastStakedAt[tokenID]); } function unStake(uint256 tokenID) external { require(msg.sender == ownerOf(tokenID), "caller must be owner"); require(tokensLastStakedAt[tokenID] == 0, "already staking"); uint256 stakeTimestamp = tokensLastStakedAt[tokenID]; tokensLastStakedAt[tokenID] = 0; emit Unstake(tokenID, msg.sender, stakeTimestamp, block.timestamp); } function transferFrom( address from, address to, uint256 tokenId ) public payable override(ERC721x) { require(enableTransfer, "transfer not enabled"); require( tokensLastStakedAt[tokenId] == 0, "Cannot transfer staked token" ); super.transferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable override(ERC721x) { require(enableTransfer, "transfer not enabled"); require( tokensLastStakedAt[tokenId] == 0, "Cannot transfer staked token" ); super.safeTransferFrom(from, to, tokenId, _data); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","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":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAt","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenUnlocked","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":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unstakedAt","type":"uint256"}],"name":"Unstake","type":"event"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvedContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_contract","type":"address"}],"name":"freeId","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":"string","name":"_prefixURI","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":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"isUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"lockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockMap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"lockMapIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintAddr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"prefixURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"payable","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_prefixURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enableMint","type":"bool"}],"name":"setMintStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enableTransfer","type":"bool"}],"name":"setTransferStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"soulBonding","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"","type":"uint256"}],"name":"tokensLastStakedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"unStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"unlockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_contracts","type":"address[]"},{"internalType":"bool[]","name":"_values","type":"bool[]"}],"name":"updateApprovedContracts","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615355806100206000396000f3fe6080604052600436106102465760003560e01c8063650b00f611610139578063a694fc3a116100b6578063c87b56dd1161007a578063c87b56dd1461087f578063e58306f9146108bc578063e985e9c5146108e5578063f2fde38b14610922578063f4a0a5281461094b578063f62d18881461097457610246565b8063a694fc3a14610797578063ac52e644146107c0578063b1a6505f146107e9578063b88d4fde14610826578063c6004ed61461084257610246565b80638da5cb5b116100fd5780638da5cb5b146106c457806394d216d6146106ef57806395d89b4114610718578063a0c5407814610743578063a22cb4651461076e57610246565b8063650b00f6146105cb5780636817c76c1461060857806370a0823114610633578063715018a61461067057806372abc8b71461068757610246565b80632cba8123116101c7578063493770cc1161018b578063493770cc146104d657806349a758a3146104ff57806355f804b31461053c5780635d3eea91146105655780636352211e1461058e57610246565b80632cba8123146103ec57806335b504c51461042957806340a9c8df1461046657806342842e0e1461048f578063453c2310146104ab57610246565b80631249c58b1161020e5780631249c58b1461034957806318160ddd146103535780631f85e3ca1461037e57806323b872dd146103a75780632799cde0146103c357610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b357806309308e5d146102f0578063095ea7b31461032d575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d91906139a0565b61099d565b60405161027f91906139e8565b60405180910390f35b34801561029457600080fd5b5061029d6109fe565b6040516102aa9190613a93565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d59190613aeb565b610a99565b6040516102e79190613b59565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613ba0565b610b21565b6040516103249190613bef565b60405180910390f35b61034760048036038101906103429190613c0a565b610b46565b005b610351610b56565b005b34801561035f57600080fd5b50610368610d2a565b6040516103759190613bef565b60405180910390f35b34801561038a57600080fd5b506103a560048036038101906103a09190613c76565b610d53565b005b6103c160048036038101906103bc9190613ca3565b610d78565b005b3480156103cf57600080fd5b506103ea60048036038101906103e59190613aeb565b610e2d565b005b3480156103f857600080fd5b50610413600480360381019061040e9190613cf6565b610e81565b6040516104209190613b59565b60405180910390f35b34801561043557600080fd5b50610450600480360381019061044b9190613aeb565b610ec3565b60405161045d9190613bef565b60405180910390f35b34801561047257600080fd5b5061048d60048036038101906104889190613aeb565b610edb565b005b6104a960048036038101906104a49190613ca3565b610f2f565b005b3480156104b757600080fd5b506104c0610f4f565b6040516104cd9190613bef565b60405180910390f35b3480156104e257600080fd5b506104fd60048036038101906104f89190613c76565b610f55565b005b34801561050b57600080fd5b5061052660048036038101906105219190613aeb565b610f7a565b6040516105339190613b59565b60405180910390f35b34801561054857600080fd5b50610563600480360381019061055e9190613d9b565b610fad565b005b34801561057157600080fd5b5061058c60048036038101906105879190613aeb565b610fcb565b005b34801561059a57600080fd5b506105b560048036038101906105b09190613aeb565b611109565b6040516105c29190613b59565b60405180910390f35b3480156105d757600080fd5b506105f260048036038101906105ed9190613aeb565b61111b565b6040516105ff9190613bef565b60405180910390f35b34801561061457600080fd5b5061061d611133565b60405161062a9190613bef565b60405180910390f35b34801561063f57600080fd5b5061065a60048036038101906106559190613de8565b611139565b6040516106679190613bef565b60405180910390f35b34801561067c57600080fd5b506106856111fa565b005b34801561069357600080fd5b506106ae60048036038101906106a99190613aeb565b61120e565b6040516106bb91906139e8565b60405180910390f35b3480156106d057600080fd5b506106d961122d565b6040516106e69190613b59565b60405180910390f35b3480156106fb57600080fd5b5061071660048036038101906107119190613ba0565b611257565b005b34801561072457600080fd5b5061072d6112ad565b60405161073a9190613a93565b60405180910390f35b34801561074f57600080fd5b50610758611348565b6040516107659190613a93565b60405180910390f35b34801561077a57600080fd5b5061079560048036038101906107909190613e15565b6113d6565b005b3480156107a357600080fd5b506107be60048036038101906107b99190613aeb565b6114ea565b005b3480156107cc57600080fd5b506107e760048036038101906107e29190613f01565b61161f565b005b3480156107f557600080fd5b50610810600480360381019061080b9190613de8565b61173c565b60405161081d91906139e8565b60405180910390f35b610840600480360381019061083b91906140b2565b61175c565b005b34801561084e57600080fd5b5061086960048036038101906108649190613de8565b611813565b6040516108769190613bef565b60405180910390f35b34801561088b57600080fd5b506108a660048036038101906108a19190613aeb565b61182b565b6040516108b39190613a93565b60405180910390f35b3480156108c857600080fd5b506108e360048036038101906108de9190613c0a565b6118a4565b005b3480156108f157600080fd5b5061090c60048036038101906109079190614135565b6118ba565b60405161091991906139e8565b60405180910390f35b34801561092e57600080fd5b5061094960048036038101906109449190613de8565b611957565b005b34801561095757600080fd5b50610972600480360381019061096d9190613aeb565b6119da565b005b34801561098057600080fd5b5061099b60048036038101906109969190614216565b6119ec565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109f757506109f682611d0a565b5b9050919050565b6060610a08611d9c565b6002018054610a169061428e565b80601f0160208091040260200160405190810160405280929190818152602001828054610a429061428e565b8015610a8f5780601f10610a6457610100808354040283529160200191610a8f565b820191906000526020600020905b815481529060010190602001808311610a7257829003601f168201915b5050505050905090565b6000610aa482611dc9565b610ada576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ae2611d9c565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610b5282826001611e3a565b5050565b606c60019054906101000a900460ff16610ba5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9c9061430b565b60405180910390fd5b606b54341015610bea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be190614377565b60405180910390fd5b606a54606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610c6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c64906143e3565b60405180910390fd5b6001606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610cbd9190614432565b92505081905550610ccf336001611f8f565b33606e6000610cdc610d2a565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000610d34611f9d565b610d3c611d9c565b60010154610d48611d9c565b600001540303905090565b610d5b611fa6565b80606c60016101000a81548160ff02191690831515021790555050565b606c60009054906101000a900460ff16610dc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbe906144b2565b60405180910390fd5b6000606f60008381526020019081526020016000205414610e1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e149061451e565b60405180910390fd5b610e28838383612024565b505050565b610e3681611dc9565b610e75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6c9061458a565b60405180910390fd5b610e7e8161207c565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606f6020528060005260406000206000915090505481565b610ee481611dc9565b610f23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1a9061458a565b60405180910390fd5b610f2c816122e8565b50565b610f4a8383836040518060200160405280600081525061175c565b505050565b606a5481565b610f5d611fa6565b80606c60006101000a81548160ff02191690831515021790555050565b606e6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610fb5611fa6565b818160699182610fc6929190614761565b505050565b610fd481611109565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110389061487d565b60405180910390fd5b6000606f60008381526020019081526020016000205414611097576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108e906148e9565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c2823383426040516110fd9493929190614909565b60405180910390a15050565b6000611114826126c3565b9050919050565b60666020528060005260406000206000915090505481565b606b5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111a0576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff6111b1611d9c565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611202611fa6565b61120c60006127d6565b565b6000806066600084815260200190815260200160002054149050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61126082611dc9565b61129f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112969061458a565b60405180910390fd5b6112a9828261289c565b5050565b60606112b7611d9c565b60030180546112c59061428e565b80601f01602080910402602001604051908101604052809291908181526020018280546112f19061428e565b801561133e5780601f106113135761010080835404028352916020019161133e565b820191906000526020600020905b81548152906001019060200180831161132157829003601f168201915b5050505050905090565b606980546113559061428e565b80601f01602080910402602001604051908101604052809291908181526020018280546113819061428e565b80156113ce5780601f106113a3576101008083540402835291602001916113ce565b820191906000526020600020905b8154815290600101906020018083116113b157829003601f168201915b505050505081565b806113df611d9c565b60070160006113ec612c79565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611499612c79565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516114de91906139e8565b60405180910390a35050565b6114f381611109565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611560576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115579061487d565b60405180910390fd5b6000606f600083815260200190815260200160002054146115b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ad906148e9565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f6000858152602001908152602001600020546040516116149392919061494e565b60405180910390a150565b611627611fa6565b81819050848490501461166f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611666906149d1565b60405180910390fd5b60005b84849050811015611735578282828181106116905761168f6149f1565b5b90506020020160208101906116a59190613c76565b606560008787858181106116bc576116bb6149f1565b5b90506020020160208101906116d19190613de8565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061172d90614a20565b915050611672565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606c60009054906101000a900460ff166117ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a2906144b2565b60405180910390fd5b6000606f60008481526020019081526020016000205414611801576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f89061451e565b60405180910390fd5b61180d84848484612c81565b50505050565b606d6020528060005260406000206000915090505481565b606061183682611dc9565b611875576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186c90614ab4565b60405180910390fd5b61187e82612cdb565b60405160200161188e9190614b36565b6040516020818303038152906040529050919050565b6118ac611fa6565b6118b68282611f8f565b5050565b60006118c4611d9c565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61195f611fa6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c590614bca565b60405180910390fd5b6119d7816127d6565b50565b6119e2611fa6565b80606b8190555050565b6119f4612d79565b60000160019054906101000a900460ff16611a2857611a11612d79565b60000160009054906101000a900460ff1615611a31565b611a30612da6565b5b611a70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a6790614c5c565b60405180910390fd5b6000611a7a612d79565b60000160019054906101000a900460ff161590508015611add576001611a9e612d79565b60000160016101000a81548160ff0219169083151502179055506001611ac2612d79565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff16159050808015611b0e5750600160008054906101000a900460ff1660ff16105b80611b3b5750611b1d30612dbd565b158015611b3a5750600160008054906101000a900460ff1660ff16145b5b611b7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7190614cee565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611bb7576001600060016101000a81548160ff0219169083151502179055505b611c2b6040518060400160405280600881526020017f546f6b656e52756e0000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f5441544100000000000000000000000000000000000000000000000000000000815250612de0565b8260699081611c3a9190614d0e565b506001606c60006101000a81548160ff0219169083151502179055506000606c60016101000a81548160ff0219169083151502179055506001606a819055506000606b819055508015611cda5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051611cd19190614e28565b60405180910390a15b508015611d06576000611ceb612d79565b60000160016101000a81548160ff0219169083151502179055505b5050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611d6557506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611d955750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611dd4611f9d565b11158015611dec5750611de5611d9c565b6000015482105b8015611e33575060007c0100000000000000000000000000000000000000000000000000000000611e1b611d9c565b60040160008581526020019081526020016000205416145b9050919050565b6000611e4583611109565b90508115611ed0578073ffffffffffffffffffffffffffffffffffffffff16611e6c612c79565b73ffffffffffffffffffffffffffffffffffffffff1614611ecf57611e9881611e93612c79565b6118ba565b611ece576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83611ed9611d9c565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b611f998282612e45565b5050565b60006001905090565b611fae613025565b73ffffffffffffffffffffffffffffffffffffffff16611fcc61122d565b73ffffffffffffffffffffffffffffffffffffffff1614612022576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201990614e8f565b60405180910390fd5b565b61202d8161120e565b61206c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161206390614efb565b60405180910390fd5b61207783838361302d565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612108576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ff90614f67565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461219b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219290614fd3565b60405180910390fd5b6000600160666000848152602001908152602001600020546121bd9190614432565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061229b90614a20565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236b90614f67565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000810361240c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124039061503f565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461259657600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550506125fb565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506066600084815260200190815260200160002060008154809291906126759061505f565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b6000816126ce611f9d565b1161279f576126db611d9c565b600401600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361279e576000810361279957612729611d9c565b600001548210612765576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b61276e611d9c565b600401600083600190039350838152602001908152602001600020549050600081036127d157612766565b6127d1565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612929576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292090614f67565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081036129c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b8906150d4565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612b4b57600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612bb0565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612c2a9061505f565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612c8a8261120e565b612cc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cc090614efb565b60405180910390fd5b612cd584848484613385565b50505050565b6060612ce682611dc9565b612d1c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612d266133f8565b90506000815103612d465760405180602001604052806000815250612d71565b80612d508461348a565b604051602001612d619291906150f4565b6040516020818303038152906040525b915050919050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16612e2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e269061518a565b60405180910390fd5b612e3982826134da565b612e41613540565b5050565b6000612e4f611d9c565b60000154905060008203612e8f576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e9c6000848385613599565b600160406001901b178202612eaf611d9c565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612f1c83612f0d600086600061359f565b612f16856135c7565b176135d7565b612f24611d9c565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612fc657808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612f8b565b5060008203613001576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8061300a611d9c565b6000018190555050506130206000848385613602565b505050565b600033905090565b6000613038826126c3565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461309f576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806130ab84613608565b915091506130c181876130bc612c79565b613638565b61310d576130d6866130d1612c79565b6118ba565b61310c576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613173576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131808686866001613599565b801561318b57600082555b613193611d9c565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460019003919050819055506131ea611d9c565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061326b8561324788888761359f565b7c0200000000000000000000000000000000000000000000000000000000176135d7565b613273611d9c565b60040160008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361331557600060018501905060006132c4611d9c565b60040160008381526020019081526020016000205403613313576132e6611d9c565b60000154811461331257836132f9611d9c565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461337d8686866001613602565b505050505050565b613390848484610d78565b60008373ffffffffffffffffffffffffffffffffffffffff163b146133f2576133bb8484848461367c565b6133f1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060606980546134079061428e565b80601f01602080910402602001604051908101604052809291908181526020018280546134339061428e565b80156134805780601f1061345557610100808354040283529160200191613480565b820191906000526020600020905b81548152906001019060200180831161346357829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b6001156134c557600184039350600a81066030018453600a81049050806134a3575b50828103602084039350808452505050919050565b6134e2612d79565b60000160019054906101000a900460ff16613532576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135299061521c565b60405180910390fd5b61353c82826137cc565b5050565b600060019054906101000a900460ff1661358f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135869061518a565b60405180910390fd5b613597613871565b565b50505050565b60008060e883901c905060e86135b68686846138ca565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000806000613615611d9c565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026136a2612c79565b8786866040518563ffffffff1660e01b81526004016136c49493929190615291565b6020604051808303816000875af192505050801561370057506040513d601f19601f820116820180604052508101906136fd91906152f2565b60015b613779573d8060008114613730576040519150601f19603f3d011682016040523d82523d6000602084013e613735565b606091505b506000815103613771576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6137d4612d79565b60000160019054906101000a900460ff16613824576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161381b9061521c565b60405180910390fd5b8161382d611d9c565b600201908161383c9190614d0e565b5080613846611d9c565b60030190816138559190614d0e565b5061385e611f9d565b613866611d9c565b600001819055505050565b600060019054906101000a900460ff166138c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138b79061518a565b60405180910390fd5b6138c86138d3565b565b60009392505050565b600060019054906101000a900460ff16613922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139199061518a565b60405180910390fd5b61393261392d613025565b6127d6565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61397d81613948565b811461398857600080fd5b50565b60008135905061399a81613974565b92915050565b6000602082840312156139b6576139b561393e565b5b60006139c48482850161398b565b91505092915050565b60008115159050919050565b6139e2816139cd565b82525050565b60006020820190506139fd60008301846139d9565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613a3d578082015181840152602081019050613a22565b60008484015250505050565b6000601f19601f8301169050919050565b6000613a6582613a03565b613a6f8185613a0e565b9350613a7f818560208601613a1f565b613a8881613a49565b840191505092915050565b60006020820190508181036000830152613aad8184613a5a565b905092915050565b6000819050919050565b613ac881613ab5565b8114613ad357600080fd5b50565b600081359050613ae581613abf565b92915050565b600060208284031215613b0157613b0061393e565b5b6000613b0f84828501613ad6565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613b4382613b18565b9050919050565b613b5381613b38565b82525050565b6000602082019050613b6e6000830184613b4a565b92915050565b613b7d81613b38565b8114613b8857600080fd5b50565b600081359050613b9a81613b74565b92915050565b60008060408385031215613bb757613bb661393e565b5b6000613bc585828601613ad6565b9250506020613bd685828601613b8b565b9150509250929050565b613be981613ab5565b82525050565b6000602082019050613c046000830184613be0565b92915050565b60008060408385031215613c2157613c2061393e565b5b6000613c2f85828601613b8b565b9250506020613c4085828601613ad6565b9150509250929050565b613c53816139cd565b8114613c5e57600080fd5b50565b600081359050613c7081613c4a565b92915050565b600060208284031215613c8c57613c8b61393e565b5b6000613c9a84828501613c61565b91505092915050565b600080600060608486031215613cbc57613cbb61393e565b5b6000613cca86828701613b8b565b9350506020613cdb86828701613b8b565b9250506040613cec86828701613ad6565b9150509250925092565b60008060408385031215613d0d57613d0c61393e565b5b6000613d1b85828601613ad6565b9250506020613d2c85828601613ad6565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613d5b57613d5a613d36565b5b8235905067ffffffffffffffff811115613d7857613d77613d3b565b5b602083019150836001820283011115613d9457613d93613d40565b5b9250929050565b60008060208385031215613db257613db161393e565b5b600083013567ffffffffffffffff811115613dd057613dcf613943565b5b613ddc85828601613d45565b92509250509250929050565b600060208284031215613dfe57613dfd61393e565b5b6000613e0c84828501613b8b565b91505092915050565b60008060408385031215613e2c57613e2b61393e565b5b6000613e3a85828601613b8b565b9250506020613e4b85828601613c61565b9150509250929050565b60008083601f840112613e6b57613e6a613d36565b5b8235905067ffffffffffffffff811115613e8857613e87613d3b565b5b602083019150836020820283011115613ea457613ea3613d40565b5b9250929050565b60008083601f840112613ec157613ec0613d36565b5b8235905067ffffffffffffffff811115613ede57613edd613d3b565b5b602083019150836020820283011115613efa57613ef9613d40565b5b9250929050565b60008060008060408587031215613f1b57613f1a61393e565b5b600085013567ffffffffffffffff811115613f3957613f38613943565b5b613f4587828801613e55565b9450945050602085013567ffffffffffffffff811115613f6857613f67613943565b5b613f7487828801613eab565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613fbf82613a49565b810181811067ffffffffffffffff82111715613fde57613fdd613f87565b5b80604052505050565b6000613ff1613934565b9050613ffd8282613fb6565b919050565b600067ffffffffffffffff82111561401d5761401c613f87565b5b61402682613a49565b9050602081019050919050565b82818337600083830152505050565b600061405561405084614002565b613fe7565b90508281526020810184848401111561407157614070613f82565b5b61407c848285614033565b509392505050565b600082601f83011261409957614098613d36565b5b81356140a9848260208601614042565b91505092915050565b600080600080608085870312156140cc576140cb61393e565b5b60006140da87828801613b8b565b94505060206140eb87828801613b8b565b93505060406140fc87828801613ad6565b925050606085013567ffffffffffffffff81111561411d5761411c613943565b5b61412987828801614084565b91505092959194509250565b6000806040838503121561414c5761414b61393e565b5b600061415a85828601613b8b565b925050602061416b85828601613b8b565b9150509250929050565b600067ffffffffffffffff8211156141905761418f613f87565b5b61419982613a49565b9050602081019050919050565b60006141b96141b484614175565b613fe7565b9050828152602081018484840111156141d5576141d4613f82565b5b6141e0848285614033565b509392505050565b600082601f8301126141fd576141fc613d36565b5b813561420d8482602086016141a6565b91505092915050565b60006020828403121561422c5761422b61393e565b5b600082013567ffffffffffffffff81111561424a57614249613943565b5b614256848285016141e8565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806142a657607f821691505b6020821081036142b9576142b861425f565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b60006142f5601083613a0e565b9150614300826142bf565b602082019050919050565b60006020820190508181036000830152614324816142e8565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b6000614361601283613a0e565b915061436c8261432b565b602082019050919050565b6000602082019050818103600083015261439081614354565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006143cd601383613a0e565b91506143d882614397565b602082019050919050565b600060208201905081810360008301526143fc816143c0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061443d82613ab5565b915061444883613ab5565b92508282019050808211156144605761445f614403565b5b92915050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b600061449c601483613a0e565b91506144a782614466565b602082019050919050565b600060208201905081810360008301526144cb8161448f565b9050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b6000614508601c83613a0e565b9150614513826144d2565b602082019050919050565b60006020820190508181036000830152614537816144fb565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b6000614574600c83613a0e565b915061457f8261453e565b602082019050919050565b600060208201905081810360008301526145a381614567565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026146177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826145da565b61462186836145da565b95508019841693508086168417925050509392505050565b6000819050919050565b600061465e61465961465484613ab5565b614639565b613ab5565b9050919050565b6000819050919050565b61467883614643565b61468c61468482614665565b8484546145e7565b825550505050565b600090565b6146a1614694565b6146ac81848461466f565b505050565b5b818110156146d0576146c5600082614699565b6001810190506146b2565b5050565b601f821115614715576146e6816145b5565b6146ef846145ca565b810160208510156146fe578190505b61471261470a856145ca565b8301826146b1565b50505b505050565b600082821c905092915050565b60006147386000198460080261471a565b1980831691505092915050565b60006147518383614727565b9150826002028217905092915050565b61476b83836145aa565b67ffffffffffffffff81111561478457614783613f87565b5b61478e825461428e565b6147998282856146d4565b6000601f8311600181146147c857600084156147b6578287013590505b6147c08582614745565b865550614828565b601f1984166147d6866145b5565b60005b828110156147fe578489013582556001820191506020850194506020810190506147d9565b8683101561481b5784890135614817601f891682614727565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b6000614867601483613a0e565b915061487282614831565b602082019050919050565b600060208201905081810360008301526148968161485a565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b60006148d3600f83613a0e565b91506148de8261489d565b602082019050919050565b60006020820190508181036000830152614902816148c6565b9050919050565b600060808201905061491e6000830187613be0565b61492b6020830186613b4a565b6149386040830185613be0565b6149456060830184613be0565b95945050505050565b60006060820190506149636000830186613be0565b6149706020830185613b4a565b61497d6040830184613be0565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b60006149bb600783613a0e565b91506149c682614985565b602082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614a2b82613ab5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a5d57614a5c614403565b5b600182019050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614a9e600f83613a0e565b9150614aa982614a68565b602082019050919050565b60006020820190508181036000830152614acd81614a91565b9050919050565b600081905092915050565b6000614aea82613a03565b614af48185614ad4565b9350614b04818560208601613a1f565b80840191505092915050565b50565b6000614b20600083614ad4565b9150614b2b82614b10565b600082019050919050565b6000614b428284614adf565b9150614b4d82614b13565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614bb4602683613a0e565b9150614bbf82614b58565b604082019050919050565b60006020820190508181036000830152614be381614ba7565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b6000614c46603783613a0e565b9150614c5182614bea565b604082019050919050565b60006020820190508181036000830152614c7581614c39565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000614cd8602e83613a0e565b9150614ce382614c7c565b604082019050919050565b60006020820190508181036000830152614d0781614ccb565b9050919050565b614d1782613a03565b67ffffffffffffffff811115614d3057614d2f613f87565b5b614d3a825461428e565b614d458282856146d4565b600060209050601f831160018114614d785760008415614d66578287015190505b614d708582614745565b865550614dd8565b601f198416614d86866145b5565b60005b82811015614dae57848901518255600182019150602085019450602081019050614d89565b86831015614dcb5784890151614dc7601f891682614727565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b6000614e12614e0d614e0884614de0565b614639565b614dea565b9050919050565b614e2281614df7565b82525050565b6000602082019050614e3d6000830184614e19565b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614e79602083613a0e565b9150614e8482614e43565b602082019050919050565b60006020820190508181036000830152614ea881614e6c565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b6000614ee5600f83613a0e565b9150614ef082614eaf565b602082019050919050565b60006020820190508181036000830152614f1481614ed8565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b6000614f51601183613a0e565b9150614f5c82614f1b565b602082019050919050565b60006020820190508181036000830152614f8081614f44565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b6000614fbd601b83613a0e565b9150614fc882614f87565b602082019050919050565b60006020820190508181036000830152614fec81614fb0565b9050919050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b6000615029601783613a0e565b915061503482614ff3565b602082019050919050565b600060208201905081810360008301526150588161501c565b9050919050565b600061506a82613ab5565b91506000820361507d5761507c614403565b5b600182039050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b60006150be600d83613a0e565b91506150c982615088565b602082019050919050565b600060208201905081810360008301526150ed816150b1565b9050919050565b60006151008285614adf565b915061510c8284614adf565b91508190509392505050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000615174602b83613a0e565b915061517f82615118565b604082019050919050565b600060208201905081810360008301526151a381615167565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000615206603483613a0e565b9150615211826151aa565b604082019050919050565b60006020820190508181036000830152615235816151f9565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006152638261523c565b61526d8185615247565b935061527d818560208601613a1f565b61528681613a49565b840191505092915050565b60006080820190506152a66000830187613b4a565b6152b36020830186613b4a565b6152c06040830185613be0565b81810360608301526152d28184615258565b905095945050505050565b6000815190506152ec81613974565b92915050565b6000602082840312156153085761530761393e565b5b6000615316848285016152dd565b9150509291505056fea2646970667358221220b1e3dce81c0cb90aa019b523675be0c189f3bbad73af430e9a421ca5035c101a64736f6c63430008120033
Deployed Bytecode
0x6080604052600436106102465760003560e01c8063650b00f611610139578063a694fc3a116100b6578063c87b56dd1161007a578063c87b56dd1461087f578063e58306f9146108bc578063e985e9c5146108e5578063f2fde38b14610922578063f4a0a5281461094b578063f62d18881461097457610246565b8063a694fc3a14610797578063ac52e644146107c0578063b1a6505f146107e9578063b88d4fde14610826578063c6004ed61461084257610246565b80638da5cb5b116100fd5780638da5cb5b146106c457806394d216d6146106ef57806395d89b4114610718578063a0c5407814610743578063a22cb4651461076e57610246565b8063650b00f6146105cb5780636817c76c1461060857806370a0823114610633578063715018a61461067057806372abc8b71461068757610246565b80632cba8123116101c7578063493770cc1161018b578063493770cc146104d657806349a758a3146104ff57806355f804b31461053c5780635d3eea91146105655780636352211e1461058e57610246565b80632cba8123146103ec57806335b504c51461042957806340a9c8df1461046657806342842e0e1461048f578063453c2310146104ab57610246565b80631249c58b1161020e5780631249c58b1461034957806318160ddd146103535780631f85e3ca1461037e57806323b872dd146103a75780632799cde0146103c357610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b357806309308e5d146102f0578063095ea7b31461032d575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d91906139a0565b61099d565b60405161027f91906139e8565b60405180910390f35b34801561029457600080fd5b5061029d6109fe565b6040516102aa9190613a93565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d59190613aeb565b610a99565b6040516102e79190613b59565b60405180910390f35b3480156102fc57600080fd5b5061031760048036038101906103129190613ba0565b610b21565b6040516103249190613bef565b60405180910390f35b61034760048036038101906103429190613c0a565b610b46565b005b610351610b56565b005b34801561035f57600080fd5b50610368610d2a565b6040516103759190613bef565b60405180910390f35b34801561038a57600080fd5b506103a560048036038101906103a09190613c76565b610d53565b005b6103c160048036038101906103bc9190613ca3565b610d78565b005b3480156103cf57600080fd5b506103ea60048036038101906103e59190613aeb565b610e2d565b005b3480156103f857600080fd5b50610413600480360381019061040e9190613cf6565b610e81565b6040516104209190613b59565b60405180910390f35b34801561043557600080fd5b50610450600480360381019061044b9190613aeb565b610ec3565b60405161045d9190613bef565b60405180910390f35b34801561047257600080fd5b5061048d60048036038101906104889190613aeb565b610edb565b005b6104a960048036038101906104a49190613ca3565b610f2f565b005b3480156104b757600080fd5b506104c0610f4f565b6040516104cd9190613bef565b60405180910390f35b3480156104e257600080fd5b506104fd60048036038101906104f89190613c76565b610f55565b005b34801561050b57600080fd5b5061052660048036038101906105219190613aeb565b610f7a565b6040516105339190613b59565b60405180910390f35b34801561054857600080fd5b50610563600480360381019061055e9190613d9b565b610fad565b005b34801561057157600080fd5b5061058c60048036038101906105879190613aeb565b610fcb565b005b34801561059a57600080fd5b506105b560048036038101906105b09190613aeb565b611109565b6040516105c29190613b59565b60405180910390f35b3480156105d757600080fd5b506105f260048036038101906105ed9190613aeb565b61111b565b6040516105ff9190613bef565b60405180910390f35b34801561061457600080fd5b5061061d611133565b60405161062a9190613bef565b60405180910390f35b34801561063f57600080fd5b5061065a60048036038101906106559190613de8565b611139565b6040516106679190613bef565b60405180910390f35b34801561067c57600080fd5b506106856111fa565b005b34801561069357600080fd5b506106ae60048036038101906106a99190613aeb565b61120e565b6040516106bb91906139e8565b60405180910390f35b3480156106d057600080fd5b506106d961122d565b6040516106e69190613b59565b60405180910390f35b3480156106fb57600080fd5b5061071660048036038101906107119190613ba0565b611257565b005b34801561072457600080fd5b5061072d6112ad565b60405161073a9190613a93565b60405180910390f35b34801561074f57600080fd5b50610758611348565b6040516107659190613a93565b60405180910390f35b34801561077a57600080fd5b5061079560048036038101906107909190613e15565b6113d6565b005b3480156107a357600080fd5b506107be60048036038101906107b99190613aeb565b6114ea565b005b3480156107cc57600080fd5b506107e760048036038101906107e29190613f01565b61161f565b005b3480156107f557600080fd5b50610810600480360381019061080b9190613de8565b61173c565b60405161081d91906139e8565b60405180910390f35b610840600480360381019061083b91906140b2565b61175c565b005b34801561084e57600080fd5b5061086960048036038101906108649190613de8565b611813565b6040516108769190613bef565b60405180910390f35b34801561088b57600080fd5b506108a660048036038101906108a19190613aeb565b61182b565b6040516108b39190613a93565b60405180910390f35b3480156108c857600080fd5b506108e360048036038101906108de9190613c0a565b6118a4565b005b3480156108f157600080fd5b5061090c60048036038101906109079190614135565b6118ba565b60405161091991906139e8565b60405180910390f35b34801561092e57600080fd5b5061094960048036038101906109449190613de8565b611957565b005b34801561095757600080fd5b50610972600480360381019061096d9190613aeb565b6119da565b005b34801561098057600080fd5b5061099b60048036038101906109969190614216565b6119ec565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109f757506109f682611d0a565b5b9050919050565b6060610a08611d9c565b6002018054610a169061428e565b80601f0160208091040260200160405190810160405280929190818152602001828054610a429061428e565b8015610a8f5780601f10610a6457610100808354040283529160200191610a8f565b820191906000526020600020905b815481529060010190602001808311610a7257829003601f168201915b5050505050905090565b6000610aa482611dc9565b610ada576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ae2611d9c565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610b5282826001611e3a565b5050565b606c60019054906101000a900460ff16610ba5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9c9061430b565b60405180910390fd5b606b54341015610bea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be190614377565b60405180910390fd5b606a54606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610c6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c64906143e3565b60405180910390fd5b6001606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610cbd9190614432565b92505081905550610ccf336001611f8f565b33606e6000610cdc610d2a565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000610d34611f9d565b610d3c611d9c565b60010154610d48611d9c565b600001540303905090565b610d5b611fa6565b80606c60016101000a81548160ff02191690831515021790555050565b606c60009054906101000a900460ff16610dc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbe906144b2565b60405180910390fd5b6000606f60008381526020019081526020016000205414610e1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e149061451e565b60405180910390fd5b610e28838383612024565b505050565b610e3681611dc9565b610e75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6c9061458a565b60405180910390fd5b610e7e8161207c565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606f6020528060005260406000206000915090505481565b610ee481611dc9565b610f23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1a9061458a565b60405180910390fd5b610f2c816122e8565b50565b610f4a8383836040518060200160405280600081525061175c565b505050565b606a5481565b610f5d611fa6565b80606c60006101000a81548160ff02191690831515021790555050565b606e6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610fb5611fa6565b818160699182610fc6929190614761565b505050565b610fd481611109565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611041576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110389061487d565b60405180910390fd5b6000606f60008381526020019081526020016000205414611097576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108e906148e9565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c2823383426040516110fd9493929190614909565b60405180910390a15050565b6000611114826126c3565b9050919050565b60666020528060005260406000206000915090505481565b606b5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111a0576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff6111b1611d9c565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611202611fa6565b61120c60006127d6565b565b6000806066600084815260200190815260200160002054149050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61126082611dc9565b61129f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112969061458a565b60405180910390fd5b6112a9828261289c565b5050565b60606112b7611d9c565b60030180546112c59061428e565b80601f01602080910402602001604051908101604052809291908181526020018280546112f19061428e565b801561133e5780601f106113135761010080835404028352916020019161133e565b820191906000526020600020905b81548152906001019060200180831161132157829003601f168201915b5050505050905090565b606980546113559061428e565b80601f01602080910402602001604051908101604052809291908181526020018280546113819061428e565b80156113ce5780601f106113a3576101008083540402835291602001916113ce565b820191906000526020600020905b8154815290600101906020018083116113b157829003601f168201915b505050505081565b806113df611d9c565b60070160006113ec612c79565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611499612c79565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516114de91906139e8565b60405180910390a35050565b6114f381611109565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611560576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115579061487d565b60405180910390fd5b6000606f600083815260200190815260200160002054146115b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ad906148e9565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f6000858152602001908152602001600020546040516116149392919061494e565b60405180910390a150565b611627611fa6565b81819050848490501461166f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611666906149d1565b60405180910390fd5b60005b84849050811015611735578282828181106116905761168f6149f1565b5b90506020020160208101906116a59190613c76565b606560008787858181106116bc576116bb6149f1565b5b90506020020160208101906116d19190613de8565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061172d90614a20565b915050611672565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606c60009054906101000a900460ff166117ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a2906144b2565b60405180910390fd5b6000606f60008481526020019081526020016000205414611801576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f89061451e565b60405180910390fd5b61180d84848484612c81565b50505050565b606d6020528060005260406000206000915090505481565b606061183682611dc9565b611875576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186c90614ab4565b60405180910390fd5b61187e82612cdb565b60405160200161188e9190614b36565b6040516020818303038152906040529050919050565b6118ac611fa6565b6118b68282611f8f565b5050565b60006118c4611d9c565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61195f611fa6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c590614bca565b60405180910390fd5b6119d7816127d6565b50565b6119e2611fa6565b80606b8190555050565b6119f4612d79565b60000160019054906101000a900460ff16611a2857611a11612d79565b60000160009054906101000a900460ff1615611a31565b611a30612da6565b5b611a70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a6790614c5c565b60405180910390fd5b6000611a7a612d79565b60000160019054906101000a900460ff161590508015611add576001611a9e612d79565b60000160016101000a81548160ff0219169083151502179055506001611ac2612d79565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff16159050808015611b0e5750600160008054906101000a900460ff1660ff16105b80611b3b5750611b1d30612dbd565b158015611b3a5750600160008054906101000a900460ff1660ff16145b5b611b7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7190614cee565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611bb7576001600060016101000a81548160ff0219169083151502179055505b611c2b6040518060400160405280600881526020017f546f6b656e52756e0000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f5441544100000000000000000000000000000000000000000000000000000000815250612de0565b8260699081611c3a9190614d0e565b506001606c60006101000a81548160ff0219169083151502179055506000606c60016101000a81548160ff0219169083151502179055506001606a819055506000606b819055508015611cda5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051611cd19190614e28565b60405180910390a15b508015611d06576000611ceb612d79565b60000160016101000a81548160ff0219169083151502179055505b5050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611d6557506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611d955750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611dd4611f9d565b11158015611dec5750611de5611d9c565b6000015482105b8015611e33575060007c0100000000000000000000000000000000000000000000000000000000611e1b611d9c565b60040160008581526020019081526020016000205416145b9050919050565b6000611e4583611109565b90508115611ed0578073ffffffffffffffffffffffffffffffffffffffff16611e6c612c79565b73ffffffffffffffffffffffffffffffffffffffff1614611ecf57611e9881611e93612c79565b6118ba565b611ece576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83611ed9611d9c565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b611f998282612e45565b5050565b60006001905090565b611fae613025565b73ffffffffffffffffffffffffffffffffffffffff16611fcc61122d565b73ffffffffffffffffffffffffffffffffffffffff1614612022576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201990614e8f565b60405180910390fd5b565b61202d8161120e565b61206c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161206390614efb565b60405180910390fd5b61207783838361302d565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612108576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ff90614f67565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461219b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219290614fd3565b60405180910390fd5b6000600160666000848152602001908152602001600020546121bd9190614432565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061229b90614a20565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236b90614f67565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000810361240c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124039061503f565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461259657600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550506125fb565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506066600084815260200190815260200160002060008154809291906126759061505f565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b6000816126ce611f9d565b1161279f576126db611d9c565b600401600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361279e576000810361279957612729611d9c565b600001548210612765576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b61276e611d9c565b600401600083600190039350838152602001908152602001600020549050600081036127d157612766565b6127d1565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612929576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161292090614f67565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081036129c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b8906150d4565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612b4b57600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612bb0565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612c2a9061505f565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612c8a8261120e565b612cc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cc090614efb565b60405180910390fd5b612cd584848484613385565b50505050565b6060612ce682611dc9565b612d1c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612d266133f8565b90506000815103612d465760405180602001604052806000815250612d71565b80612d508461348a565b604051602001612d619291906150f4565b6040516020818303038152906040525b915050919050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16612e2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e269061518a565b60405180910390fd5b612e3982826134da565b612e41613540565b5050565b6000612e4f611d9c565b60000154905060008203612e8f576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e9c6000848385613599565b600160406001901b178202612eaf611d9c565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612f1c83612f0d600086600061359f565b612f16856135c7565b176135d7565b612f24611d9c565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612fc657808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612f8b565b5060008203613001576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8061300a611d9c565b6000018190555050506130206000848385613602565b505050565b600033905090565b6000613038826126c3565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461309f576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806130ab84613608565b915091506130c181876130bc612c79565b613638565b61310d576130d6866130d1612c79565b6118ba565b61310c576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613173576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131808686866001613599565b801561318b57600082555b613193611d9c565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460019003919050819055506131ea611d9c565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061326b8561324788888761359f565b7c0200000000000000000000000000000000000000000000000000000000176135d7565b613273611d9c565b60040160008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361331557600060018501905060006132c4611d9c565b60040160008381526020019081526020016000205403613313576132e6611d9c565b60000154811461331257836132f9611d9c565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461337d8686866001613602565b505050505050565b613390848484610d78565b60008373ffffffffffffffffffffffffffffffffffffffff163b146133f2576133bb8484848461367c565b6133f1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060606980546134079061428e565b80601f01602080910402602001604051908101604052809291908181526020018280546134339061428e565b80156134805780601f1061345557610100808354040283529160200191613480565b820191906000526020600020905b81548152906001019060200180831161346357829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b6001156134c557600184039350600a81066030018453600a81049050806134a3575b50828103602084039350808452505050919050565b6134e2612d79565b60000160019054906101000a900460ff16613532576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135299061521c565b60405180910390fd5b61353c82826137cc565b5050565b600060019054906101000a900460ff1661358f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135869061518a565b60405180910390fd5b613597613871565b565b50505050565b60008060e883901c905060e86135b68686846138ca565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000806000613615611d9c565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026136a2612c79565b8786866040518563ffffffff1660e01b81526004016136c49493929190615291565b6020604051808303816000875af192505050801561370057506040513d601f19601f820116820180604052508101906136fd91906152f2565b60015b613779573d8060008114613730576040519150601f19603f3d011682016040523d82523d6000602084013e613735565b606091505b506000815103613771576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6137d4612d79565b60000160019054906101000a900460ff16613824576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161381b9061521c565b60405180910390fd5b8161382d611d9c565b600201908161383c9190614d0e565b5080613846611d9c565b60030190816138559190614d0e565b5061385e611f9d565b613866611d9c565b600001819055505050565b600060019054906101000a900460ff166138c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138b79061518a565b60405180910390fd5b6138c86138d3565b565b60009392505050565b600060019054906101000a900460ff16613922576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139199061518a565b60405180910390fd5b61393261392d613025565b6127d6565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61397d81613948565b811461398857600080fd5b50565b60008135905061399a81613974565b92915050565b6000602082840312156139b6576139b561393e565b5b60006139c48482850161398b565b91505092915050565b60008115159050919050565b6139e2816139cd565b82525050565b60006020820190506139fd60008301846139d9565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613a3d578082015181840152602081019050613a22565b60008484015250505050565b6000601f19601f8301169050919050565b6000613a6582613a03565b613a6f8185613a0e565b9350613a7f818560208601613a1f565b613a8881613a49565b840191505092915050565b60006020820190508181036000830152613aad8184613a5a565b905092915050565b6000819050919050565b613ac881613ab5565b8114613ad357600080fd5b50565b600081359050613ae581613abf565b92915050565b600060208284031215613b0157613b0061393e565b5b6000613b0f84828501613ad6565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613b4382613b18565b9050919050565b613b5381613b38565b82525050565b6000602082019050613b6e6000830184613b4a565b92915050565b613b7d81613b38565b8114613b8857600080fd5b50565b600081359050613b9a81613b74565b92915050565b60008060408385031215613bb757613bb661393e565b5b6000613bc585828601613ad6565b9250506020613bd685828601613b8b565b9150509250929050565b613be981613ab5565b82525050565b6000602082019050613c046000830184613be0565b92915050565b60008060408385031215613c2157613c2061393e565b5b6000613c2f85828601613b8b565b9250506020613c4085828601613ad6565b9150509250929050565b613c53816139cd565b8114613c5e57600080fd5b50565b600081359050613c7081613c4a565b92915050565b600060208284031215613c8c57613c8b61393e565b5b6000613c9a84828501613c61565b91505092915050565b600080600060608486031215613cbc57613cbb61393e565b5b6000613cca86828701613b8b565b9350506020613cdb86828701613b8b565b9250506040613cec86828701613ad6565b9150509250925092565b60008060408385031215613d0d57613d0c61393e565b5b6000613d1b85828601613ad6565b9250506020613d2c85828601613ad6565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613d5b57613d5a613d36565b5b8235905067ffffffffffffffff811115613d7857613d77613d3b565b5b602083019150836001820283011115613d9457613d93613d40565b5b9250929050565b60008060208385031215613db257613db161393e565b5b600083013567ffffffffffffffff811115613dd057613dcf613943565b5b613ddc85828601613d45565b92509250509250929050565b600060208284031215613dfe57613dfd61393e565b5b6000613e0c84828501613b8b565b91505092915050565b60008060408385031215613e2c57613e2b61393e565b5b6000613e3a85828601613b8b565b9250506020613e4b85828601613c61565b9150509250929050565b60008083601f840112613e6b57613e6a613d36565b5b8235905067ffffffffffffffff811115613e8857613e87613d3b565b5b602083019150836020820283011115613ea457613ea3613d40565b5b9250929050565b60008083601f840112613ec157613ec0613d36565b5b8235905067ffffffffffffffff811115613ede57613edd613d3b565b5b602083019150836020820283011115613efa57613ef9613d40565b5b9250929050565b60008060008060408587031215613f1b57613f1a61393e565b5b600085013567ffffffffffffffff811115613f3957613f38613943565b5b613f4587828801613e55565b9450945050602085013567ffffffffffffffff811115613f6857613f67613943565b5b613f7487828801613eab565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613fbf82613a49565b810181811067ffffffffffffffff82111715613fde57613fdd613f87565b5b80604052505050565b6000613ff1613934565b9050613ffd8282613fb6565b919050565b600067ffffffffffffffff82111561401d5761401c613f87565b5b61402682613a49565b9050602081019050919050565b82818337600083830152505050565b600061405561405084614002565b613fe7565b90508281526020810184848401111561407157614070613f82565b5b61407c848285614033565b509392505050565b600082601f83011261409957614098613d36565b5b81356140a9848260208601614042565b91505092915050565b600080600080608085870312156140cc576140cb61393e565b5b60006140da87828801613b8b565b94505060206140eb87828801613b8b565b93505060406140fc87828801613ad6565b925050606085013567ffffffffffffffff81111561411d5761411c613943565b5b61412987828801614084565b91505092959194509250565b6000806040838503121561414c5761414b61393e565b5b600061415a85828601613b8b565b925050602061416b85828601613b8b565b9150509250929050565b600067ffffffffffffffff8211156141905761418f613f87565b5b61419982613a49565b9050602081019050919050565b60006141b96141b484614175565b613fe7565b9050828152602081018484840111156141d5576141d4613f82565b5b6141e0848285614033565b509392505050565b600082601f8301126141fd576141fc613d36565b5b813561420d8482602086016141a6565b91505092915050565b60006020828403121561422c5761422b61393e565b5b600082013567ffffffffffffffff81111561424a57614249613943565b5b614256848285016141e8565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806142a657607f821691505b6020821081036142b9576142b861425f565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b60006142f5601083613a0e565b9150614300826142bf565b602082019050919050565b60006020820190508181036000830152614324816142e8565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b6000614361601283613a0e565b915061436c8261432b565b602082019050919050565b6000602082019050818103600083015261439081614354565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006143cd601383613a0e565b91506143d882614397565b602082019050919050565b600060208201905081810360008301526143fc816143c0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061443d82613ab5565b915061444883613ab5565b92508282019050808211156144605761445f614403565b5b92915050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b600061449c601483613a0e565b91506144a782614466565b602082019050919050565b600060208201905081810360008301526144cb8161448f565b9050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b6000614508601c83613a0e565b9150614513826144d2565b602082019050919050565b60006020820190508181036000830152614537816144fb565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b6000614574600c83613a0e565b915061457f8261453e565b602082019050919050565b600060208201905081810360008301526145a381614567565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026146177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826145da565b61462186836145da565b95508019841693508086168417925050509392505050565b6000819050919050565b600061465e61465961465484613ab5565b614639565b613ab5565b9050919050565b6000819050919050565b61467883614643565b61468c61468482614665565b8484546145e7565b825550505050565b600090565b6146a1614694565b6146ac81848461466f565b505050565b5b818110156146d0576146c5600082614699565b6001810190506146b2565b5050565b601f821115614715576146e6816145b5565b6146ef846145ca565b810160208510156146fe578190505b61471261470a856145ca565b8301826146b1565b50505b505050565b600082821c905092915050565b60006147386000198460080261471a565b1980831691505092915050565b60006147518383614727565b9150826002028217905092915050565b61476b83836145aa565b67ffffffffffffffff81111561478457614783613f87565b5b61478e825461428e565b6147998282856146d4565b6000601f8311600181146147c857600084156147b6578287013590505b6147c08582614745565b865550614828565b601f1984166147d6866145b5565b60005b828110156147fe578489013582556001820191506020850194506020810190506147d9565b8683101561481b5784890135614817601f891682614727565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b6000614867601483613a0e565b915061487282614831565b602082019050919050565b600060208201905081810360008301526148968161485a565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b60006148d3600f83613a0e565b91506148de8261489d565b602082019050919050565b60006020820190508181036000830152614902816148c6565b9050919050565b600060808201905061491e6000830187613be0565b61492b6020830186613b4a565b6149386040830185613be0565b6149456060830184613be0565b95945050505050565b60006060820190506149636000830186613be0565b6149706020830185613b4a565b61497d6040830184613be0565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b60006149bb600783613a0e565b91506149c682614985565b602082019050919050565b600060208201905081810360008301526149ea816149ae565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614a2b82613ab5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a5d57614a5c614403565b5b600182019050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614a9e600f83613a0e565b9150614aa982614a68565b602082019050919050565b60006020820190508181036000830152614acd81614a91565b9050919050565b600081905092915050565b6000614aea82613a03565b614af48185614ad4565b9350614b04818560208601613a1f565b80840191505092915050565b50565b6000614b20600083614ad4565b9150614b2b82614b10565b600082019050919050565b6000614b428284614adf565b9150614b4d82614b13565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614bb4602683613a0e565b9150614bbf82614b58565b604082019050919050565b60006020820190508181036000830152614be381614ba7565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b6000614c46603783613a0e565b9150614c5182614bea565b604082019050919050565b60006020820190508181036000830152614c7581614c39565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000614cd8602e83613a0e565b9150614ce382614c7c565b604082019050919050565b60006020820190508181036000830152614d0781614ccb565b9050919050565b614d1782613a03565b67ffffffffffffffff811115614d3057614d2f613f87565b5b614d3a825461428e565b614d458282856146d4565b600060209050601f831160018114614d785760008415614d66578287015190505b614d708582614745565b865550614dd8565b601f198416614d86866145b5565b60005b82811015614dae57848901518255600182019150602085019450602081019050614d89565b86831015614dcb5784890151614dc7601f891682614727565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b6000614e12614e0d614e0884614de0565b614639565b614dea565b9050919050565b614e2281614df7565b82525050565b6000602082019050614e3d6000830184614e19565b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614e79602083613a0e565b9150614e8482614e43565b602082019050919050565b60006020820190508181036000830152614ea881614e6c565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b6000614ee5600f83613a0e565b9150614ef082614eaf565b602082019050919050565b60006020820190508181036000830152614f1481614ed8565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b6000614f51601183613a0e565b9150614f5c82614f1b565b602082019050919050565b60006020820190508181036000830152614f8081614f44565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b6000614fbd601b83613a0e565b9150614fc882614f87565b602082019050919050565b60006020820190508181036000830152614fec81614fb0565b9050919050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b6000615029601783613a0e565b915061503482614ff3565b602082019050919050565b600060208201905081810360008301526150588161501c565b9050919050565b600061506a82613ab5565b91506000820361507d5761507c614403565b5b600182039050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b60006150be600d83613a0e565b91506150c982615088565b602082019050919050565b600060208201905081810360008301526150ed816150b1565b9050919050565b60006151008285614adf565b915061510c8284614adf565b91508190509392505050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000615174602b83613a0e565b915061517f82615118565b604082019050919050565b600060208201905081810360008301526151a381615167565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000615206603483613a0e565b9150615211826151aa565b604082019050919050565b60006020820190508181036000830152615235816151f9565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006152638261523c565b61526d8185615247565b935061527d818560208601613a1f565b61528681613a49565b840191505092915050565b60006080820190506152a66000830187613b4a565b6152b36020830186613b4a565b6152c06040830185613be0565b81810360608301526152d28184615258565b905095945050505050565b6000815190506152ec81613974565b92915050565b6000602082840312156153085761530761393e565b5b6000615316848285016152dd565b9150509291505056fea2646970667358221220b1e3dce81c0cb90aa019b523675be0c189f3bbad73af430e9a421ca5035c101a64736f6c63430008120033
Deployed Bytecode Sourcemap
135090:4106:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85847:292;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50346:124;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56938:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22861:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56655:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;136142:361;;;:::i;:::-;;45831:371;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137448:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138407:367;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86777:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22783:71;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135382:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86919:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63801:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135156:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137559:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135329:46;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137157:108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138019:380;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51787:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22723:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135190:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47111:257;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21384:103;;;;;;;;;;;;;:::i;:::-;;23303:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20743:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87065:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50546:128;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135126:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57520:258;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137688:323;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23425;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22659:57;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;138782:411;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135279:43;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136902:247;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136015:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57935:188;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21642:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137346:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135707:300;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85847:292;85998:4;85590:10;86056:21;;86040:37;;;:12;:37;;;;:91;;;;86094:37;86118:12;86094:23;:37::i;:::-;86040:91;86020:111;;85847:292;;;:::o;50346:124::-;50400:13;50433:23;:21;:23::i;:::-;:29;;50426:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50346:124;:::o;56938:242::-;57014:7;57039:16;57047:7;57039;:16::i;:::-;57034:64;;57064:34;;;;;;;;;;;;;;57034:64;57118:23;:21;:23::i;:::-;:39;;:48;57158:7;57118:48;;;;;;;;;;;:54;;;;;;;;;;;;57111:61;;56938:242;;;:::o;22861:94::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;56655:124::-;56744:27;56753:2;56757:7;56766:4;56744:8;:27::i;:::-;56655:124;;:::o;136142:361::-;136192:10;;;;;;;;;;;136184:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;136255:9;;136242;:22;;136234:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;136329:12;;136306:8;:20;136315:10;136306:20;;;;;;;;;;;;;;;;:35;136298:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;136410:1;136386:8;:20;136395:10;136386:20;;;;;;;;;;;;;;;;:25;;;;;;;:::i;:::-;;;;;;;;136422:23;136431:10;136443:1;136422:8;:23::i;:::-;136485:10;136456:11;:26;136468:13;:11;:13::i;:::-;136456:26;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;136142:361::o;45831:371::-;45892:7;46168:15;:13;:15::i;:::-;46129:23;:21;:23::i;:::-;:36;;;46089:23;:21;:23::i;:::-;:37;;;:76;:94;46082:101;;45831:371;:::o;137448:103::-;20629:13;:11;:13::i;:::-;137532:11:::1;137519:10;;:24;;;;;;;;;;;;;;;;;;137448:103:::0;:::o;138407:367::-;138558:14;;;;;;;;;;;138550:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;138661:1;138630:18;:27;138649:7;138630:27;;;;;;;;;;;;:32;138608:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;138729:37;138748:4;138754:2;138758:7;138729:18;:37::i;:::-;138407:367;;;:::o;86777:134::-;86851:12;86859:3;86851:7;:12::i;:::-;86843:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;86891:12;86899:3;86891:7;:12::i;:::-;86777:134;:::o;22783:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;135382:53::-;;;;;;;;;;;;;;;;;:::o;86919:138::-;86995:12;87003:3;86995:7;:12::i;:::-;86987:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;87035:14;87045:3;87035:9;:14::i;:::-;86919:138;:::o;63801:193::-;63947:39;63964:4;63970:2;63974:7;63947:39;;;;;;;;;;;;:16;:39::i;:::-;63801:193;;;:::o;135156:27::-;;;;:::o;137559:119::-;20629:13;:11;:13::i;:::-;137655:15:::1;137638:14;;:32;;;;;;;;;;;;;;;;;;137559:119:::0;:::o;135329:46::-;;;;;;;;;;;;;;;;;;;;;;:::o;137157:108::-;20629:13;:11;:13::i;:::-;137247:10:::1;;137235:9;:22;;;;;;;:::i;:::-;;137157:108:::0;;:::o;138019:380::-;138095:16;138103:7;138095;:16::i;:::-;138081:30;;:10;:30;;;138073:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;138186:1;138155:18;:27;138174:7;138155:27;;;;;;;;;;;;:32;138147:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;138220:22;138245:18;:27;138264:7;138245:27;;;;;;;;;;;;138220:52;;138313:1;138283:18;:27;138302:7;138283:27;;;;;;;;;;;:31;;;;138330:61;138338:7;138347:10;138359:14;138375:15;138330:61;;;;;;;;;:::i;:::-;;;;;;;;138062:337;138019:380;:::o;51787:152::-;51859:7;51902:27;51921:7;51902:18;:27::i;:::-;51879:52;;51787:152;;;:::o;22723:53::-;;;;;;;;;;;;;;;;;:::o;135190:24::-;;;;:::o;47111:257::-;47183:7;47224:1;47207:19;;:5;:19;;;47203:60;;47235:28;;;;;;;;;;;;;;47203:60;42259:13;47281:23;:21;:23::i;:::-;:42;;:49;47324:5;47281:49;;;;;;;;;;;;;;;;:79;47274:86;;47111:257;;;:::o;21384:103::-;20629:13;:11;:13::i;:::-;21449:30:::1;21476:1;21449:18;:30::i;:::-;21384:103::o:0;23303:114::-;23366:4;23408:1;23390:9;:14;23400:3;23390:14;;;;;;;;;;;;:19;23383:26;;23303:114;;;:::o;20743:87::-;20789:7;20816:6;;;;;;;;;;;20809:13;;20743:87;:::o;87065:164::-;87158:12;87166:3;87158:7;:12::i;:::-;87150:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;87198:23;87206:3;87211:9;87198:7;:23::i;:::-;87065:164;;:::o;50546:128::-;50602:13;50635:23;:21;:23::i;:::-;:31;;50628:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50546:128;:::o;135126:23::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;57520:258::-;57691:8;57615:23;:21;:23::i;:::-;:42;;:63;57658:19;:17;:19::i;:::-;57615:63;;;;;;;;;;;;;;;:73;57679:8;57615:73;;;;;;;;;;;;;;;;:84;;;;;;;;;;;;;;;;;;57751:8;57715:55;;57730:19;:17;:19::i;:::-;57715:55;;;57761:8;57715:55;;;;;;:::i;:::-;;;;;;;;57520:258;;:::o;137688:323::-;137762:16;137770:7;137762;:16::i;:::-;137748:30;;:10;:30;;;137740:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;137853:1;137822:18;:27;137841:7;137822:27;;;;;;;;;;;;:32;137814:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;137917:15;137887:18;:27;137906:7;137887:27;;;;;;;;;;;:45;;;;137948:55;137954:7;137963:10;137975:18;:27;137994:7;137975:27;;;;;;;;;;;;137948:55;;;;;;;;:::i;:::-;;;;;;;;137688:323;:::o;23425:::-;20629:13;:11;:13::i;:::-;23598:7:::1;;:14;;23577:10;;:17;;:35;23569:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;23640:9;23635:105;23659:10;;:17;;23655:1;:21;23635:105;;;23730:7;;23738:1;23730:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;23696:16;:31;23713:10;;23724:1;23713:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;23696:31;;;;;;;;;;;;;;;;:44;;;;;;;;;;;;;;;;;;23678:3;;;;;:::i;:::-;;;;23635:105;;;;23425:323:::0;;;;:::o;22659:57::-;;;;;;;;;;;;;;;;;;;;;;:::o;138782:411::-;138966:14;;;;;;;;;;;138958:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;139069:1;139038:18;:27;139057:7;139038:27;;;;;;;;;;;;:32;139016:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;139137:48;139160:4;139166:2;139170:7;139179:5;139137:22;:48::i;:::-;138782:411;;;;:::o;135279:43::-;;;;;;;;;;;;;;;;;:::o;136902:247::-;137004:13;137043:17;137051:8;137043:7;:17::i;:::-;137035:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;137112:24;137127:8;137112:14;:24::i;:::-;137098:43;;;;;;;;:::i;:::-;;;;;;;;;;;;;137091:50;;136902:247;;;:::o;136015:119::-;20629:13;:11;:13::i;:::-;136098:28:::1;136107:8;136117;136098;:28::i;:::-;136015:119:::0;;:::o;57935:188::-;58032:4;58056:23;:21;:23::i;:::-;:42;;:49;58099:5;58056:49;;;;;;;;;;;;;;;:59;58106:8;58056:59;;;;;;;;;;;;;;;;;;;;;;;;;58049:66;;57935:188;;;;:::o;21642:201::-;20629:13;:11;:13::i;:::-;21751:1:::1;21731:22;;:8;:22;;::::0;21723:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;21807:28;21826:8;21807:18;:28::i;:::-;21642:201:::0;:::o;137346:94::-;20629:13;:11;:13::i;:::-;137426:6:::1;137414:9;:18;;;;137346:94:::0;:::o;135707:300::-;28047:38;:36;:38::i;:::-;:52;;;;;;;;;;;;:160;;28156:38;:36;:38::i;:::-;:51;;;;;;;;;;;;28155:52;28047:160;;;28119:16;:14;:16::i;:::-;28047:160;28025:265;;;;;;;;;;;;:::i;:::-;;;;;;;;;28303:19;28326:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28325:53;28303:75;;28393:14;28389:179;;;28479:4;28424:38;:36;:38::i;:::-;:52;;;:59;;;;;;;;;;;;;;;;;;28552:4;28498:38;:36;:38::i;:::-;:51;;;:58;;;;;;;;;;;;;;;;;;28389:179;14459:19:::1;14482:13:::0;::::1;;;;;;;;;;14481:14;14459:36;;14529:14;:34;;;;;14562:1;14547:12;::::0;::::1;;;;;;;;:16;;;14529:34;14528:108;;;;14570:44;14608:4;14570:29;:44::i;:::-;14569:45;:66;;;;;14634:1;14618:12;::::0;::::1;;;;;;;;:17;;;14569:66;14528:108;14506:204;;;;;;;;;;;;:::i;:::-;;;;;;;;;14736:1;14721:12;::::0;:16:::1;;;;;;;;;;;;;;;;;;14752:14;14748:67;;;14799:4;14783:13;;:20;;;;;;;;;;;;;;;;;;14748:67;135818:34:::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;::::0;:14:::2;:34::i;:::-;135877:10;135865:9;:22;;;;;;:::i;:::-;;135915:4;135898:14;;:21;;;;;;;;;;;;;;;;;;135943:5;135930:10;;:18;;;;;;;;;;;;;;;;;;135974:1;135959:12;:16;;;;135998:1;135986:9;:13;;;;14841:14:::1;14837:102;;;14888:5;14872:13:::0;::::1;:21;;;;;;;;;;;;;;;;;;14913:14;14925:1;14913:14;;;;;;:::i;:::-;;;;;;;;14837:102;14448:498;28598:14:::0;28594:107;;;28684:5;28629:38;:36;:38::i;:::-;:52;;;:60;;;;;;;;;;;;;;;;;;28594:107;27740:968;135707:300;:::o;49444:639::-;49529:4;49868:10;49853:25;;:11;:25;;;;:102;;;;49945:10;49930:25;;:11;:25;;;;49853:102;:179;;;;50022:10;50007:25;;:11;:25;;;;49853:179;49833:199;;49444:639;;;:::o;31665:164::-;31706:16;31735:12;31610:46;31735:27;;31807:4;31797:14;;31782:40;31665:164;:::o;58381:330::-;58446:4;58502:7;58483:15;:13;:15::i;:::-;:26;;:90;;;;;58536:23;:21;:23::i;:::-;:37;;;58526:7;:47;58483:90;:201;;;;;58683:1;43035:8;58611:23;:21;:23::i;:::-;:41;;:50;58653:7;58611:50;;;;;;;;;;;;:68;:73;58483:201;58463:221;;58381:330;;;:::o;75930:516::-;76059:13;76075:16;76083:7;76075;:16::i;:::-;76059:32;;76108:13;76104:219;;;76163:5;76140:28;;:19;:17;:19::i;:::-;:28;;;76136:187;;76192:44;76209:5;76216:19;:17;:19::i;:::-;76192:16;:44::i;:::-;76187:136;;76268:35;;;;;;;;;;;;;;76187:136;76136:187;76104:219;76392:2;76335:23;:21;:23::i;:::-;:39;;:48;76375:7;76335:48;;;;;;;;;;;:54;;;:59;;;;;;;;;;;;;;;;;;76430:7;76426:2;76410:28;;76419:5;76410:28;;;;;;;;;;;;76048:398;75930:516;;;:::o;136511:107::-;136585:25;136591:8;136601;136585:5;:25::i;:::-;136511:107;;:::o;136675:101::-;136740:7;136767:1;136760:8;;136675:101;:::o;20908:132::-;20983:12;:10;:12::i;:::-;20972:23;;:7;:5;:7::i;:::-;:23;;;20964:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;20908:132::o;86147:285::-;86320:20;86331:8;86320:10;:20::i;:::-;86312:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;86371:53;86403:5;86410:3;86415:8;86371:31;:53::i;:::-;86147:285;;;:::o;23756:447::-;23814:16;:28;23831:10;23814:28;;;;;;;;;;;;;;;;;;;;;;;;;23806:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;23930:1;23897:12;:17;23910:3;23897:17;;;;;;;;;;;:29;23915:10;23897:29;;;;;;;;;;;;;;;;:34;23875:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;23999:13;24032:1;24015:9;:14;24025:3;24015:14;;;;;;;;;;;;:18;;;;:::i;:::-;23999:34;;24066:10;24044:7;:12;24052:3;24044:12;;;;;;;;;;;:19;24057:5;24044:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;24119:5;24087:12;:17;24100:3;24087:17;;;;;;;;;;;:29;24105:10;24087:29;;;;;;;;;;;;;;;:37;;;;24135:9;:14;24145:3;24135:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;24184:10;24167:28;;24179:3;24167:28;;;;;;;;;;23795:408;23756:447;:::o;24211:675::-;24271:16;:28;24288:10;24271:28;;;;;;;;;;;;;;;;;;;;;;;;;24263:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;24332:13;24348:12;:17;24361:3;24348:17;;;;;;;;;;;:29;24366:10;24348:29;;;;;;;;;;;;;;;;24332:45;;24405:1;24396:5;:10;24388:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;24447:12;24462:9;:14;24472:3;24462:14;;;;;;;;;;;;24447:29;;24500:4;24491:5;:13;24487:274;;24521:20;24544:7;:12;24552:3;24544:12;;;;;;;;;;;:18;24557:4;24544:18;;;;;;;;;;;;;;;;;;;;;24521:41;;24599:12;24577:7;:12;24585:3;24577:12;;;;;;;;;;;:19;24590:5;24577:19;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;24655:1;24626:7;:12;24634:3;24626:12;;;;;;;;;;;:18;24639:4;24626:18;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;24706:5;24672:12;:17;24685:3;24672:17;;;;;;;;;;;:31;24690:12;24672:31;;;;;;;;;;;;;;;:39;;;;24506:217;24487:274;;;24759:1;24729:7;:12;24737:3;24729:12;;;;;;;;;;;:19;24742:5;24729:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;24487:274;24804:1;24772:12;:17;24785:3;24772:17;;;;;;;;;;;:29;24790:10;24772:29;;;;;;;;;;;;;;;:33;;;;24816:9;:14;24826:3;24816:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;24867:10;24848:30;;24862:3;24848:30;;;;;;;;;;24252:634;;24211:675;:::o;53014:1784::-;53081:14;53131:7;53112:15;:13;:15::i;:::-;:26;53108:1634;;53164:23;:21;:23::i;:::-;:41;;:50;53206:7;53164:50;;;;;;;;;;;;53155:59;;53292:1;43035:8;53264:6;:24;:29;53260:1471;;53413:1;53403:6;:11;53399:1029;;53454:23;:21;:23::i;:::-;:37;;;53443:7;:48;53439:92;;53500:31;;;;;;;;;;;;;;53439:92;54128:281;54214:23;:21;:23::i;:::-;:41;;:52;54256:9;;;;;;;54214:52;;;;;;;;;;;;54205:61;;54334:1;54324:6;:11;54372:13;54320:25;54128:281;;53399:1029;54702:13;;53260:1471;53108:1634;54759:31;;;;;;;;;;;;;;53014:1784;;;;:::o;22003:191::-;22077:16;22096:6;;;;;;;;;;;22077:25;;22122:8;22113:6;;:17;;;;;;;;;;;;;;;;;;22177:8;22146:40;;22167:8;22146:40;;;;;;;;;;;;22066:128;22003:191;:::o;24894:679::-;24972:16;:27;24989:9;24972:27;;;;;;;;;;;;;;;;;;;;;;;;;24971:28;24963:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;25032:13;25048:12;:17;25061:3;25048:17;;;;;;;;;;;:28;25066:9;25048:28;;;;;;;;;;;;;;;;25032:44;;25104:1;25095:5;:10;25087:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;25136:12;25151:9;:14;25161:3;25151:14;;;;;;;;;;;;25136:29;;25189:4;25180:5;:13;25176:274;;25210:20;25233:7;:12;25241:3;25233:12;;;;;;;;;;;:18;25246:4;25233:18;;;;;;;;;;;;;;;;;;;;;25210:41;;25288:12;25266:7;:12;25274:3;25266:12;;;;;;;;;;;:19;25279:5;25266:19;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;25344:1;25315:7;:12;25323:3;25315:12;;;;;;;;;;;:18;25328:4;25315:18;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;25395:5;25361:12;:17;25374:3;25361:17;;;;;;;;;;;:31;25379:12;25361:31;;;;;;;;;;;;;;;:39;;;;25195:217;25176:274;;;25448:1;25418:7;:12;25426:3;25418:12;;;;;;;;;;;:19;25431:5;25418:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;25176:274;25492:1;25461:12;:17;25474:3;25461:17;;;;;;;;;;;:28;25479:9;25461:28;;;;;;;;;;;;;;;:32;;;;25504:9;:14;25514:3;25504:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;25555:9;25536:29;;25550:3;25536:29;;;;;;;;;;24952:621;;24894:679;;:::o;82694:105::-;82754:7;82781:10;82774:17;;82694:105;:::o;86440:329::-;86646:20;86657:8;86646:10;:20::i;:::-;86638:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;86697:64;86733:5;86740:3;86745:8;86755:5;86697:35;:64::i;:::-;86440:329;;;;:::o;50780:318::-;50853:13;50884:16;50892:7;50884;:16::i;:::-;50879:59;;50909:29;;;;;;;;;;;;;;50879:59;50951:21;50975:10;:8;:10::i;:::-;50951:34;;51028:1;51009:7;51003:21;:26;:87;;;;;;;;;;;;;;;;;51056:7;51065:18;51075:7;51065:9;:18::i;:::-;51039:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;51003:87;50996:94;;;50780:318;;;:::o;26235:164::-;26276:16;26305:12;26168:58;26305:27;;26377:4;26367:14;;26352:40;26235:164;:::o;29216:569::-;29264:4;29635:12;29658:4;29635:28;;29674:10;29737:4;29725:17;29719:23;;29776:1;29770:2;:7;29763:14;;;;29216:569;:::o;2936:326::-;2996:4;3253:1;3231:7;:19;;;:23;3224:30;;2936:326;;;:::o;85609:230::-;16602:13;;;;;;;;;;;16594:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;85737:49:::1;85771:5;85778:7;85737:33;:49::i;:::-;85797:34;:32;:34::i;:::-;85609:230:::0;;:::o;68281:3062::-;68354:20;68377:23;:21;:23::i;:::-;:37;;;68354:60;;68441:1;68429:8;:13;68425:44;;68451:18;;;;;;;;;;;;;;68425:44;68482:61;68512:1;68516:2;68520:12;68534:8;68482:21;:61::i;:::-;69050:1;42397:2;69020:1;:26;;69019:32;69007:8;:45;68957:23;:21;:23::i;:::-;:42;;:46;69000:2;68957:46;;;;;;;;;;;;;;;;:95;;;;;;;;;;;69353:139;69390:2;69444:33;69467:1;69471:2;69475:1;69444:14;:33::i;:::-;69411:30;69432:8;69411:20;:30::i;:::-;:66;69353:18;:139::i;:::-;69295:23;:21;:23::i;:::-;:41;;:55;69337:12;69295:55;;;;;;;;;;;:197;;;;69509:16;69540:11;69569:8;69554:12;:23;69540:37;;70090:16;70086:2;70082:25;70070:37;;70462:12;70422:8;70381:1;70319:25;70260:1;70199;70172:335;70833:1;70819:12;70815:20;70773:346;70874:3;70865:7;70862:16;70773:346;;71092:7;71082:8;71079:1;71052:25;71049:1;71046;71041:59;70927:1;70918:7;70914:15;70903:26;;70773:346;;;70777:77;71164:1;71152:8;:13;71148:45;;71174:19;;;;;;;;;;;;;;71148:45;71250:3;71210:23;:21;:23::i;:::-;:37;;:43;;;;68731:2534;;71275:60;71304:1;71308:2;71312:12;71326:8;71275:20;:60::i;:::-;68343:3000;68281:3062;;:::o;18781:98::-;18834:7;18861:10;18854:17;;18781:98;:::o;60736:2969::-;60878:27;60908;60927:7;60908:18;:27::i;:::-;60878:57;;60993:4;60952:45;;60968:19;60952:45;;;60948:86;;61006:28;;;;;;;;;;;;;;60948:86;61048:27;61077:23;61104:35;61131:7;61104:26;:35::i;:::-;61047:92;;;;61239:68;61264:15;61281:4;61287:19;:17;:19::i;:::-;61239:24;:68::i;:::-;61234:180;;61327:43;61344:4;61350:19;:17;:19::i;:::-;61327:16;:43::i;:::-;61322:92;;61379:35;;;;;;;;;;;;;;61322:92;61234:180;61445:1;61431:16;;:2;:16;;;61427:52;;61456:23;;;;;;;;;;;;;;61427:52;61492:43;61514:4;61520:2;61524:7;61533:1;61492:21;:43::i;:::-;61628:15;61625:160;;;61768:1;61747:19;61740:30;61625:160;62165:23;:21;:23::i;:::-;:42;;:48;62208:4;62165:48;;;;;;;;;;;;;;;;62163:50;;;;;;;;;;;;62258:23;:21;:23::i;:::-;:42;;:46;62301:2;62258:46;;;;;;;;;;;;;;;;62256:48;;;;;;;;;;;62628:146;62665:2;62714:45;62729:4;62735:2;62739:19;62714:14;:45::i;:::-;43315:8;62686:73;62628:18;:146::i;:::-;62575:23;:21;:23::i;:::-;:41;;:50;62617:7;62575:50;;;;;;;;;;;:199;;;;62945:1;43315:8;62894:19;:47;:52;62890:699;;62967:19;62999:1;62989:7;:11;62967:33;;63180:1;63122:23;:21;:23::i;:::-;:41;;:54;63164:11;63122:54;;;;;;;;;;;;:59;63118:456;;63284:23;:21;:23::i;:::-;:37;;;63269:11;:52;63265:290;;63512:19;63455:23;:21;:23::i;:::-;:41;;:54;63497:11;63455:54;;;;;;;;;;;:76;;;;63265:290;63118:456;62948:641;62890:699;63636:7;63632:2;63617:27;;63626:4;63617:27;;;;;;;;;;;;63655:42;63676:4;63682:2;63686:7;63695:1;63655:20;:42::i;:::-;60867:2838;;;60736:2969;;;:::o;64592:407::-;64767:31;64780:4;64786:2;64790:7;64767:12;:31::i;:::-;64831:1;64813:2;:14;;;:19;64809:183;;64852:56;64883:4;64889:2;64893:7;64902:5;64852:30;:56::i;:::-;64847:145;;64936:40;;;;;;;;;;;;;;64847:145;64809:183;64592:407;;;;:::o;136784:110::-;136844:13;136877:9;136870:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136784:110;:::o;82901:1745::-;82966:17;83400:4;83393;83387:11;83383:22;83492:1;83486:4;83479:15;83567:4;83564:1;83560:12;83553:19;;83649:1;83644:3;83637:14;83753:3;83992:5;83974:428;84000:1;83974:428;;;84040:1;84035:3;84031:11;84024:18;;84211:2;84205:4;84201:13;84197:2;84193:22;84188:3;84180:36;84305:2;84299:4;84295:13;84287:21;;84372:4;83974:428;84362:25;83974:428;83978:21;84441:3;84436;84432:13;84556:4;84551:3;84547:14;84540:21;;84621:6;84616:3;84609:19;83005:1634;;;82901:1745;;;:::o;44534:160::-;28971:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28949:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;44646:40:::1;44671:5;44678:7;44646:24;:40::i;:::-;44534:160:::0;;:::o;23184:111::-;16602:13;;;;;;;;;;;16594:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;23252:35:::1;:33;:35::i;:::-;23184:111::o:0;65661:159::-;;;;;:::o;82003:311::-;82138:7;82158:16;43439:3;82184:19;:41;;82158:68;;43439:3;82252:31;82263:4;82269:2;82273:9;82252:10;:31::i;:::-;82244:40;;:62;;82237:69;;;82003:311;;;;;:::o;55898:324::-;55968:14;56201:1;56191:8;56188:15;56162:24;56158:46;56148:56;;55898:324;;;:::o;55346:450::-;55426:14;55594:16;55587:5;55583:28;55574:37;;55771:5;55757:11;55732:23;55728:41;55725:52;55718:5;55715:63;55705:73;;55346:450;;;;:::o;66485:158::-;;;;;:::o;59592:524::-;59694:27;59723:23;59764:53;59820:23;:21;:23::i;:::-;:39;;:48;59860:7;59820:48;;;;;;;;;;;59764:104;;60021:18;59998:41;;60078:19;60072:26;60053:45;;59983:126;59592:524;;;:::o;58820:659::-;58969:11;59134:16;59127:5;59123:28;59114:37;;59294:16;59283:9;59279:32;59266:45;;59444:15;59433:9;59430:30;59422:5;59411:9;59408:20;59405:56;59395:66;;58820:659;;;;;:::o;67083:736::-;67246:4;67316:2;67280:56;;;67337:19;:17;:19::i;:::-;67358:4;67364:7;67373:5;67280:99;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;67263:549;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67587:1;67570:6;:13;:18;67566:235;;67616:40;;;;;;;;;;;;;;67566:235;67759:6;67753:13;67744:6;67740:2;67736:15;67729:38;67263:549;67445:65;;;67435:75;;;:6;:75;;;;67428:82;;;67083:736;;;;;;:::o;44702:285::-;28971:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28949:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;44856:5:::1;44824:23;:21;:23::i;:::-;:29;;:37;;;;;;:::i;:::-;;44906:7;44872:23;:21;:23::i;:::-;:31;;:41;;;;;;:::i;:::-;;44964:15;:13;:15::i;:::-;44924:23;:21;:23::i;:::-;:37;;:55;;;;44702:285:::0;;:::o;20286:97::-;16602:13;;;;;;;;;;;16594:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;20349:26:::1;:24;:26::i;:::-;20286:97::o:0;81704:147::-;81841:6;81704:147;;;;;:::o;20391:113::-;16602:13;;;;;;;;;;;16594:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;20464:32:::1;20483:12;:10;:12::i;:::-;20464:18;:32::i;:::-;20391:113::o:0;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:474::-;5310:6;5318;5367:2;5355:9;5346:7;5342:23;5338:32;5335:119;;;5373:79;;:::i;:::-;5335:119;5493:1;5518:53;5563:7;5554:6;5543:9;5539:22;5518:53;:::i;:::-;5508:63;;5464:117;5620:2;5646:53;5691:7;5682:6;5671:9;5667:22;5646:53;:::i;:::-;5636:63;;5591:118;5242:474;;;;;:::o;5722:116::-;5792:21;5807:5;5792:21;:::i;:::-;5785:5;5782:32;5772:60;;5828:1;5825;5818:12;5772:60;5722:116;:::o;5844:133::-;5887:5;5925:6;5912:20;5903:29;;5941:30;5965:5;5941:30;:::i;:::-;5844:133;;;;:::o;5983:323::-;6039:6;6088:2;6076:9;6067:7;6063:23;6059:32;6056:119;;;6094:79;;:::i;:::-;6056:119;6214:1;6239:50;6281:7;6272:6;6261:9;6257:22;6239:50;:::i;:::-;6229:60;;6185:114;5983:323;;;;:::o;6312:619::-;6389:6;6397;6405;6454:2;6442:9;6433:7;6429:23;6425:32;6422:119;;;6460:79;;:::i;:::-;6422:119;6580:1;6605:53;6650:7;6641:6;6630:9;6626:22;6605:53;:::i;:::-;6595:63;;6551:117;6707:2;6733:53;6778:7;6769:6;6758:9;6754:22;6733:53;:::i;:::-;6723:63;;6678:118;6835:2;6861:53;6906:7;6897:6;6886:9;6882:22;6861:53;:::i;:::-;6851:63;;6806:118;6312:619;;;;;:::o;6937:474::-;7005:6;7013;7062:2;7050:9;7041:7;7037:23;7033:32;7030:119;;;7068:79;;:::i;:::-;7030:119;7188:1;7213:53;7258:7;7249:6;7238:9;7234:22;7213:53;:::i;:::-;7203:63;;7159:117;7315:2;7341:53;7386:7;7377:6;7366:9;7362:22;7341:53;:::i;:::-;7331:63;;7286:118;6937:474;;;;;:::o;7417:117::-;7526:1;7523;7516:12;7540:117;7649:1;7646;7639:12;7663:117;7772:1;7769;7762:12;7800:553;7858:8;7868:6;7918:3;7911:4;7903:6;7899:17;7895:27;7885:122;;7926:79;;:::i;:::-;7885:122;8039:6;8026:20;8016:30;;8069:18;8061:6;8058:30;8055:117;;;8091:79;;:::i;:::-;8055:117;8205:4;8197:6;8193:17;8181:29;;8259:3;8251:4;8243:6;8239:17;8229:8;8225:32;8222:41;8219:128;;;8266:79;;:::i;:::-;8219:128;7800:553;;;;;:::o;8359:529::-;8430:6;8438;8487:2;8475:9;8466:7;8462:23;8458:32;8455:119;;;8493:79;;:::i;:::-;8455:119;8641:1;8630:9;8626:17;8613:31;8671:18;8663:6;8660:30;8657:117;;;8693:79;;:::i;:::-;8657:117;8806:65;8863:7;8854:6;8843:9;8839:22;8806:65;:::i;:::-;8788:83;;;;8584:297;8359:529;;;;;:::o;8894:329::-;8953:6;9002:2;8990:9;8981:7;8977:23;8973:32;8970:119;;;9008:79;;:::i;:::-;8970:119;9128:1;9153:53;9198:7;9189:6;9178:9;9174:22;9153:53;:::i;:::-;9143:63;;9099:117;8894:329;;;;:::o;9229:468::-;9294:6;9302;9351:2;9339:9;9330:7;9326:23;9322:32;9319:119;;;9357:79;;:::i;:::-;9319:119;9477:1;9502:53;9547:7;9538:6;9527:9;9523:22;9502:53;:::i;:::-;9492:63;;9448:117;9604:2;9630:50;9672:7;9663:6;9652:9;9648:22;9630:50;:::i;:::-;9620:60;;9575:115;9229:468;;;;;:::o;9720:568::-;9793:8;9803:6;9853:3;9846:4;9838:6;9834:17;9830:27;9820:122;;9861:79;;:::i;:::-;9820:122;9974:6;9961:20;9951:30;;10004:18;9996:6;9993:30;9990:117;;;10026:79;;:::i;:::-;9990:117;10140:4;10132:6;10128:17;10116:29;;10194:3;10186:4;10178:6;10174:17;10164:8;10160:32;10157:41;10154:128;;;10201:79;;:::i;:::-;10154:128;9720:568;;;;;:::o;10308:565::-;10378:8;10388:6;10438:3;10431:4;10423:6;10419:17;10415:27;10405:122;;10446:79;;:::i;:::-;10405:122;10559:6;10546:20;10536:30;;10589:18;10581:6;10578:30;10575:117;;;10611:79;;:::i;:::-;10575:117;10725:4;10717:6;10713:17;10701:29;;10779:3;10771:4;10763:6;10759:17;10749:8;10745:32;10742:41;10739:128;;;10786:79;;:::i;:::-;10739:128;10308:565;;;;;:::o;10879:928::-;10998:6;11006;11014;11022;11071:2;11059:9;11050:7;11046:23;11042:32;11039:119;;;11077:79;;:::i;:::-;11039:119;11225:1;11214:9;11210:17;11197:31;11255:18;11247:6;11244:30;11241:117;;;11277:79;;:::i;:::-;11241:117;11390:80;11462:7;11453:6;11442:9;11438:22;11390:80;:::i;:::-;11372:98;;;;11168:312;11547:2;11536:9;11532:18;11519:32;11578:18;11570:6;11567:30;11564:117;;;11600:79;;:::i;:::-;11564:117;11713:77;11782:7;11773:6;11762:9;11758:22;11713:77;:::i;:::-;11695:95;;;;11490:310;10879:928;;;;;;;:::o;11813:117::-;11922:1;11919;11912:12;11936:180;11984:77;11981:1;11974:88;12081:4;12078:1;12071:15;12105:4;12102:1;12095:15;12122:281;12205:27;12227:4;12205:27;:::i;:::-;12197:6;12193:40;12335:6;12323:10;12320:22;12299:18;12287:10;12284:34;12281:62;12278:88;;;12346:18;;:::i;:::-;12278:88;12386:10;12382:2;12375:22;12165:238;12122:281;;:::o;12409:129::-;12443:6;12470:20;;:::i;:::-;12460:30;;12499:33;12527:4;12519:6;12499:33;:::i;:::-;12409:129;;;:::o;12544:307::-;12605:4;12695:18;12687:6;12684:30;12681:56;;;12717:18;;:::i;:::-;12681:56;12755:29;12777:6;12755:29;:::i;:::-;12747:37;;12839:4;12833;12829:15;12821:23;;12544:307;;;:::o;12857:146::-;12954:6;12949:3;12944;12931:30;12995:1;12986:6;12981:3;12977:16;12970:27;12857:146;;;:::o;13009:423::-;13086:5;13111:65;13127:48;13168:6;13127:48;:::i;:::-;13111:65;:::i;:::-;13102:74;;13199:6;13192:5;13185:21;13237:4;13230:5;13226:16;13275:3;13266:6;13261:3;13257:16;13254:25;13251:112;;;13282:79;;:::i;:::-;13251:112;13372:54;13419:6;13414:3;13409;13372:54;:::i;:::-;13092:340;13009:423;;;;;:::o;13451:338::-;13506:5;13555:3;13548:4;13540:6;13536:17;13532:27;13522:122;;13563:79;;:::i;:::-;13522:122;13680:6;13667:20;13705:78;13779:3;13771:6;13764:4;13756:6;13752:17;13705:78;:::i;:::-;13696:87;;13512:277;13451:338;;;;:::o;13795:943::-;13890:6;13898;13906;13914;13963:3;13951:9;13942:7;13938:23;13934:33;13931:120;;;13970:79;;:::i;:::-;13931:120;14090:1;14115:53;14160:7;14151:6;14140:9;14136:22;14115:53;:::i;:::-;14105:63;;14061:117;14217:2;14243:53;14288:7;14279:6;14268:9;14264:22;14243:53;:::i;:::-;14233:63;;14188:118;14345:2;14371:53;14416:7;14407:6;14396:9;14392:22;14371:53;:::i;:::-;14361:63;;14316:118;14501:2;14490:9;14486:18;14473:32;14532:18;14524:6;14521:30;14518:117;;;14554:79;;:::i;:::-;14518:117;14659:62;14713:7;14704:6;14693:9;14689:22;14659:62;:::i;:::-;14649:72;;14444:287;13795:943;;;;;;;:::o;14744:474::-;14812:6;14820;14869:2;14857:9;14848:7;14844:23;14840:32;14837:119;;;14875:79;;:::i;:::-;14837:119;14995:1;15020:53;15065:7;15056:6;15045:9;15041:22;15020:53;:::i;:::-;15010:63;;14966:117;15122:2;15148:53;15193:7;15184:6;15173:9;15169:22;15148:53;:::i;:::-;15138:63;;15093:118;14744:474;;;;;:::o;15224:308::-;15286:4;15376:18;15368:6;15365:30;15362:56;;;15398:18;;:::i;:::-;15362:56;15436:29;15458:6;15436:29;:::i;:::-;15428:37;;15520:4;15514;15510:15;15502:23;;15224:308;;;:::o;15538:425::-;15616:5;15641:66;15657:49;15699:6;15657:49;:::i;:::-;15641:66;:::i;:::-;15632:75;;15730:6;15723:5;15716:21;15768:4;15761:5;15757:16;15806:3;15797:6;15792:3;15788:16;15785:25;15782:112;;;15813:79;;:::i;:::-;15782:112;15903:54;15950:6;15945:3;15940;15903:54;:::i;:::-;15622:341;15538:425;;;;;:::o;15983:340::-;16039:5;16088:3;16081:4;16073:6;16069:17;16065:27;16055:122;;16096:79;;:::i;:::-;16055:122;16213:6;16200:20;16238:79;16313:3;16305:6;16298:4;16290:6;16286:17;16238:79;:::i;:::-;16229:88;;16045:278;15983:340;;;;:::o;16329:509::-;16398:6;16447:2;16435:9;16426:7;16422:23;16418:32;16415:119;;;16453:79;;:::i;:::-;16415:119;16601:1;16590:9;16586:17;16573:31;16631:18;16623:6;16620:30;16617:117;;;16653:79;;:::i;:::-;16617:117;16758:63;16813:7;16804:6;16793:9;16789:22;16758:63;:::i;:::-;16748:73;;16544:287;16329:509;;;;:::o;16844:180::-;16892:77;16889:1;16882:88;16989:4;16986:1;16979:15;17013:4;17010:1;17003:15;17030:320;17074:6;17111:1;17105:4;17101:12;17091:22;;17158:1;17152:4;17148:12;17179:18;17169:81;;17235:4;17227:6;17223:17;17213:27;;17169:81;17297:2;17289:6;17286:14;17266:18;17263:38;17260:84;;17316:18;;:::i;:::-;17260:84;17081:269;17030:320;;;:::o;17356:166::-;17496:18;17492:1;17484:6;17480:14;17473:42;17356:166;:::o;17528:366::-;17670:3;17691:67;17755:2;17750:3;17691:67;:::i;:::-;17684:74;;17767:93;17856:3;17767:93;:::i;:::-;17885:2;17880:3;17876:12;17869:19;;17528:366;;;:::o;17900:419::-;18066:4;18104:2;18093:9;18089:18;18081:26;;18153:9;18147:4;18143:20;18139:1;18128:9;18124:17;18117:47;18181:131;18307:4;18181:131;:::i;:::-;18173:139;;17900:419;;;:::o;18325:168::-;18465:20;18461:1;18453:6;18449:14;18442:44;18325:168;:::o;18499:366::-;18641:3;18662:67;18726:2;18721:3;18662:67;:::i;:::-;18655:74;;18738:93;18827:3;18738:93;:::i;:::-;18856:2;18851:3;18847:12;18840:19;;18499:366;;;:::o;18871:419::-;19037:4;19075:2;19064:9;19060:18;19052:26;;19124:9;19118:4;19114:20;19110:1;19099:9;19095:17;19088:47;19152:131;19278:4;19152:131;:::i;:::-;19144:139;;18871:419;;;:::o;19296:169::-;19436:21;19432:1;19424:6;19420:14;19413:45;19296:169;:::o;19471:366::-;19613:3;19634:67;19698:2;19693:3;19634:67;:::i;:::-;19627:74;;19710:93;19799:3;19710:93;:::i;:::-;19828:2;19823:3;19819:12;19812:19;;19471:366;;;:::o;19843:419::-;20009:4;20047:2;20036:9;20032:18;20024:26;;20096:9;20090:4;20086:20;20082:1;20071:9;20067:17;20060:47;20124:131;20250:4;20124:131;:::i;:::-;20116:139;;19843:419;;;:::o;20268:180::-;20316:77;20313:1;20306:88;20413:4;20410:1;20403:15;20437:4;20434:1;20427:15;20454:191;20494:3;20513:20;20531:1;20513:20;:::i;:::-;20508:25;;20547:20;20565:1;20547:20;:::i;:::-;20542:25;;20590:1;20587;20583:9;20576:16;;20611:3;20608:1;20605:10;20602:36;;;20618:18;;:::i;:::-;20602:36;20454:191;;;;:::o;20651:170::-;20791:22;20787:1;20779:6;20775:14;20768:46;20651:170;:::o;20827:366::-;20969:3;20990:67;21054:2;21049:3;20990:67;:::i;:::-;20983:74;;21066:93;21155:3;21066:93;:::i;:::-;21184:2;21179:3;21175:12;21168:19;;20827:366;;;:::o;21199:419::-;21365:4;21403:2;21392:9;21388:18;21380:26;;21452:9;21446:4;21442:20;21438:1;21427:9;21423:17;21416:47;21480:131;21606:4;21480:131;:::i;:::-;21472:139;;21199:419;;;:::o;21624:178::-;21764:30;21760:1;21752:6;21748:14;21741:54;21624:178;:::o;21808:366::-;21950:3;21971:67;22035:2;22030:3;21971:67;:::i;:::-;21964:74;;22047:93;22136:3;22047:93;:::i;:::-;22165:2;22160:3;22156:12;22149:19;;21808:366;;;:::o;22180:419::-;22346:4;22384:2;22373:9;22369:18;22361:26;;22433:9;22427:4;22423:20;22419:1;22408:9;22404:17;22397:47;22461:131;22587:4;22461:131;:::i;:::-;22453:139;;22180:419;;;:::o;22605:162::-;22745:14;22741:1;22733:6;22729:14;22722:38;22605:162;:::o;22773:366::-;22915:3;22936:67;23000:2;22995:3;22936:67;:::i;:::-;22929:74;;23012:93;23101:3;23012:93;:::i;:::-;23130:2;23125:3;23121:12;23114:19;;22773:366;;;:::o;23145:419::-;23311:4;23349:2;23338:9;23334:18;23326:26;;23398:9;23392:4;23388:20;23384:1;23373:9;23369:17;23362:47;23426:131;23552:4;23426:131;:::i;:::-;23418:139;;23145:419;;;:::o;23570:97::-;23629:6;23657:3;23647:13;;23570:97;;;;:::o;23673:141::-;23722:4;23745:3;23737:11;;23768:3;23765:1;23758:14;23802:4;23799:1;23789:18;23781:26;;23673:141;;;:::o;23820:93::-;23857:6;23904:2;23899;23892:5;23888:14;23884:23;23874:33;;23820:93;;;:::o;23919:107::-;23963:8;24013:5;24007:4;24003:16;23982:37;;23919:107;;;;:::o;24032:393::-;24101:6;24151:1;24139:10;24135:18;24174:97;24204:66;24193:9;24174:97;:::i;:::-;24292:39;24322:8;24311:9;24292:39;:::i;:::-;24280:51;;24364:4;24360:9;24353:5;24349:21;24340:30;;24413:4;24403:8;24399:19;24392:5;24389:30;24379:40;;24108:317;;24032:393;;;;;:::o;24431:60::-;24459:3;24480:5;24473:12;;24431:60;;;:::o;24497:142::-;24547:9;24580:53;24598:34;24607:24;24625:5;24607:24;:::i;:::-;24598:34;:::i;:::-;24580:53;:::i;:::-;24567:66;;24497:142;;;:::o;24645:75::-;24688:3;24709:5;24702:12;;24645:75;;;:::o;24726:269::-;24836:39;24867:7;24836:39;:::i;:::-;24897:91;24946:41;24970:16;24946:41;:::i;:::-;24938:6;24931:4;24925:11;24897:91;:::i;:::-;24891:4;24884:105;24802:193;24726:269;;;:::o;25001:73::-;25046:3;25001:73;:::o;25080:189::-;25157:32;;:::i;:::-;25198:65;25256:6;25248;25242:4;25198:65;:::i;:::-;25133:136;25080:189;;:::o;25275:186::-;25335:120;25352:3;25345:5;25342:14;25335:120;;;25406:39;25443:1;25436:5;25406:39;:::i;:::-;25379:1;25372:5;25368:13;25359:22;;25335:120;;;25275:186;;:::o;25467:543::-;25568:2;25563:3;25560:11;25557:446;;;25602:38;25634:5;25602:38;:::i;:::-;25686:29;25704:10;25686:29;:::i;:::-;25676:8;25672:44;25869:2;25857:10;25854:18;25851:49;;;25890:8;25875:23;;25851:49;25913:80;25969:22;25987:3;25969:22;:::i;:::-;25959:8;25955:37;25942:11;25913:80;:::i;:::-;25572:431;;25557:446;25467:543;;;:::o;26016:117::-;26070:8;26120:5;26114:4;26110:16;26089:37;;26016:117;;;;:::o;26139:169::-;26183:6;26216:51;26264:1;26260:6;26252:5;26249:1;26245:13;26216:51;:::i;:::-;26212:56;26297:4;26291;26287:15;26277:25;;26190:118;26139:169;;;;:::o;26313:295::-;26389:4;26535:29;26560:3;26554:4;26535:29;:::i;:::-;26527:37;;26597:3;26594:1;26590:11;26584:4;26581:21;26573:29;;26313:295;;;;:::o;26613:1403::-;26737:44;26777:3;26772;26737:44;:::i;:::-;26846:18;26838:6;26835:30;26832:56;;;26868:18;;:::i;:::-;26832:56;26912:38;26944:4;26938:11;26912:38;:::i;:::-;26997:67;27057:6;27049;27043:4;26997:67;:::i;:::-;27091:1;27120:2;27112:6;27109:14;27137:1;27132:632;;;;27808:1;27825:6;27822:84;;;27881:9;27876:3;27872:19;27859:33;27850:42;;27822:84;27932:67;27992:6;27985:5;27932:67;:::i;:::-;27926:4;27919:81;27781:229;27102:908;;27132:632;27184:4;27180:9;27172:6;27168:22;27218:37;27250:4;27218:37;:::i;:::-;27277:1;27291:215;27305:7;27302:1;27299:14;27291:215;;;27391:9;27386:3;27382:19;27369:33;27361:6;27354:49;27442:1;27434:6;27430:14;27420:24;;27489:2;27478:9;27474:18;27461:31;;27328:4;27325:1;27321:12;27316:17;;27291:215;;;27534:6;27525:7;27522:19;27519:186;;;27599:9;27594:3;27590:19;27577:33;27642:48;27684:4;27676:6;27672:17;27661:9;27642:48;:::i;:::-;27634:6;27627:64;27542:163;27519:186;27751:1;27747;27739:6;27735:14;27731:22;27725:4;27718:36;27139:625;;;27102:908;;26712:1304;;;26613:1403;;;:::o;28022:170::-;28162:22;28158:1;28150:6;28146:14;28139:46;28022:170;:::o;28198:366::-;28340:3;28361:67;28425:2;28420:3;28361:67;:::i;:::-;28354:74;;28437:93;28526:3;28437:93;:::i;:::-;28555:2;28550:3;28546:12;28539:19;;28198:366;;;:::o;28570:419::-;28736:4;28774:2;28763:9;28759:18;28751:26;;28823:9;28817:4;28813:20;28809:1;28798:9;28794:17;28787:47;28851:131;28977:4;28851:131;:::i;:::-;28843:139;;28570:419;;;:::o;28995:165::-;29135:17;29131:1;29123:6;29119:14;29112:41;28995:165;:::o;29166:366::-;29308:3;29329:67;29393:2;29388:3;29329:67;:::i;:::-;29322:74;;29405:93;29494:3;29405:93;:::i;:::-;29523:2;29518:3;29514:12;29507:19;;29166:366;;;:::o;29538:419::-;29704:4;29742:2;29731:9;29727:18;29719:26;;29791:9;29785:4;29781:20;29777:1;29766:9;29762:17;29755:47;29819:131;29945:4;29819:131;:::i;:::-;29811:139;;29538:419;;;:::o;29963:553::-;30140:4;30178:3;30167:9;30163:19;30155:27;;30192:71;30260:1;30249:9;30245:17;30236:6;30192:71;:::i;:::-;30273:72;30341:2;30330:9;30326:18;30317:6;30273:72;:::i;:::-;30355;30423:2;30412:9;30408:18;30399:6;30355:72;:::i;:::-;30437;30505:2;30494:9;30490:18;30481:6;30437:72;:::i;:::-;29963:553;;;;;;;:::o;30522:442::-;30671:4;30709:2;30698:9;30694:18;30686:26;;30722:71;30790:1;30779:9;30775:17;30766:6;30722:71;:::i;:::-;30803:72;30871:2;30860:9;30856:18;30847:6;30803:72;:::i;:::-;30885;30953:2;30942:9;30938:18;30929:6;30885:72;:::i;:::-;30522:442;;;;;;:::o;30970:157::-;31110:9;31106:1;31098:6;31094:14;31087:33;30970:157;:::o;31133:365::-;31275:3;31296:66;31360:1;31355:3;31296:66;:::i;:::-;31289:73;;31371:93;31460:3;31371:93;:::i;:::-;31489:2;31484:3;31480:12;31473:19;;31133:365;;;:::o;31504:419::-;31670:4;31708:2;31697:9;31693:18;31685:26;;31757:9;31751:4;31747:20;31743:1;31732:9;31728:17;31721:47;31785:131;31911:4;31785:131;:::i;:::-;31777:139;;31504:419;;;:::o;31929:180::-;31977:77;31974:1;31967:88;32074:4;32071:1;32064:15;32098:4;32095:1;32088:15;32115:233;32154:3;32177:24;32195:5;32177:24;:::i;:::-;32168:33;;32223:66;32216:5;32213:77;32210:103;;32293:18;;:::i;:::-;32210:103;32340:1;32333:5;32329:13;32322:20;;32115:233;;;:::o;32354:165::-;32494:17;32490:1;32482:6;32478:14;32471:41;32354:165;:::o;32525:366::-;32667:3;32688:67;32752:2;32747:3;32688:67;:::i;:::-;32681:74;;32764:93;32853:3;32764:93;:::i;:::-;32882:2;32877:3;32873:12;32866:19;;32525:366;;;:::o;32897:419::-;33063:4;33101:2;33090:9;33086:18;33078:26;;33150:9;33144:4;33140:20;33136:1;33125:9;33121:17;33114:47;33178:131;33304:4;33178:131;:::i;:::-;33170:139;;32897:419;;;:::o;33322:148::-;33424:11;33461:3;33446:18;;33322:148;;;;:::o;33476:390::-;33582:3;33610:39;33643:5;33610:39;:::i;:::-;33665:89;33747:6;33742:3;33665:89;:::i;:::-;33658:96;;33763:65;33821:6;33816:3;33809:4;33802:5;33798:16;33763:65;:::i;:::-;33853:6;33848:3;33844:16;33837:23;;33586:280;33476:390;;;;:::o;33872:114::-;;:::o;33992:400::-;34152:3;34173:84;34255:1;34250:3;34173:84;:::i;:::-;34166:91;;34266:93;34355:3;34266:93;:::i;:::-;34384:1;34379:3;34375:11;34368:18;;33992:400;;;:::o;34398:541::-;34631:3;34653:95;34744:3;34735:6;34653:95;:::i;:::-;34646:102;;34765:148;34909:3;34765:148;:::i;:::-;34758:155;;34930:3;34923:10;;34398:541;;;;:::o;34945:225::-;35085:34;35081:1;35073:6;35069:14;35062:58;35154:8;35149:2;35141:6;35137:15;35130:33;34945:225;:::o;35176:366::-;35318:3;35339:67;35403:2;35398:3;35339:67;:::i;:::-;35332:74;;35415:93;35504:3;35415:93;:::i;:::-;35533:2;35528:3;35524:12;35517:19;;35176:366;;;:::o;35548:419::-;35714:4;35752:2;35741:9;35737:18;35729:26;;35801:9;35795:4;35791:20;35787:1;35776:9;35772:17;35765:47;35829:131;35955:4;35829:131;:::i;:::-;35821:139;;35548:419;;;:::o;35973:242::-;36113:34;36109:1;36101:6;36097:14;36090:58;36182:25;36177:2;36169:6;36165:15;36158:50;35973:242;:::o;36221:366::-;36363:3;36384:67;36448:2;36443:3;36384:67;:::i;:::-;36377:74;;36460:93;36549:3;36460:93;:::i;:::-;36578:2;36573:3;36569:12;36562:19;;36221:366;;;:::o;36593:419::-;36759:4;36797:2;36786:9;36782:18;36774:26;;36846:9;36840:4;36836:20;36832:1;36821:9;36817:17;36810:47;36874:131;37000:4;36874:131;:::i;:::-;36866:139;;36593:419;;;:::o;37018:233::-;37158:34;37154:1;37146:6;37142:14;37135:58;37227:16;37222:2;37214:6;37210:15;37203:41;37018:233;:::o;37257:366::-;37399:3;37420:67;37484:2;37479:3;37420:67;:::i;:::-;37413:74;;37496:93;37585:3;37496:93;:::i;:::-;37614:2;37609:3;37605:12;37598:19;;37257:366;;;:::o;37629:419::-;37795:4;37833:2;37822:9;37818:18;37810:26;;37882:9;37876:4;37872:20;37868:1;37857:9;37853:17;37846:47;37910:131;38036:4;37910:131;:::i;:::-;37902:139;;37629:419;;;:::o;38054:1395::-;38171:37;38204:3;38171:37;:::i;:::-;38273:18;38265:6;38262:30;38259:56;;;38295:18;;:::i;:::-;38259:56;38339:38;38371:4;38365:11;38339:38;:::i;:::-;38424:67;38484:6;38476;38470:4;38424:67;:::i;:::-;38518:1;38542:4;38529:17;;38574:2;38566:6;38563:14;38591:1;38586:618;;;;39248:1;39265:6;39262:77;;;39314:9;39309:3;39305:19;39299:26;39290:35;;39262:77;39365:67;39425:6;39418:5;39365:67;:::i;:::-;39359:4;39352:81;39221:222;38556:887;;38586:618;38638:4;38634:9;38626:6;38622:22;38672:37;38704:4;38672:37;:::i;:::-;38731:1;38745:208;38759:7;38756:1;38753:14;38745:208;;;38838:9;38833:3;38829:19;38823:26;38815:6;38808:42;38889:1;38881:6;38877:14;38867:24;;38936:2;38925:9;38921:18;38908:31;;38782:4;38779:1;38775:12;38770:17;;38745:208;;;38981:6;38972:7;38969:19;38966:179;;;39039:9;39034:3;39030:19;39024:26;39082:48;39124:4;39116:6;39112:17;39101:9;39082:48;:::i;:::-;39074:6;39067:64;38989:156;38966:179;39191:1;39187;39179:6;39175:14;39171:22;39165:4;39158:36;38593:611;;;38556:887;;38146:1303;;;38054:1395;;:::o;39455:85::-;39500:7;39529:5;39518:16;;39455:85;;;:::o;39546:86::-;39581:7;39621:4;39614:5;39610:16;39599:27;;39546:86;;;:::o;39638:154::-;39694:9;39727:59;39743:42;39752:32;39778:5;39752:32;:::i;:::-;39743:42;:::i;:::-;39727:59;:::i;:::-;39714:72;;39638:154;;;:::o;39798:143::-;39891:43;39928:5;39891:43;:::i;:::-;39886:3;39879:56;39798:143;;:::o;39947:234::-;40046:4;40084:2;40073:9;40069:18;40061:26;;40097:77;40171:1;40160:9;40156:17;40147:6;40097:77;:::i;:::-;39947:234;;;;:::o;40187:182::-;40327:34;40323:1;40315:6;40311:14;40304:58;40187:182;:::o;40375:366::-;40517:3;40538:67;40602:2;40597:3;40538:67;:::i;:::-;40531:74;;40614:93;40703:3;40614:93;:::i;:::-;40732:2;40727:3;40723:12;40716:19;;40375:366;;;:::o;40747:419::-;40913:4;40951:2;40940:9;40936:18;40928:26;;41000:9;40994:4;40990:20;40986:1;40975:9;40971:17;40964:47;41028:131;41154:4;41028:131;:::i;:::-;41020:139;;40747:419;;;:::o;41172:165::-;41312:17;41308:1;41300:6;41296:14;41289:41;41172:165;:::o;41343:366::-;41485:3;41506:67;41570:2;41565:3;41506:67;:::i;:::-;41499:74;;41582:93;41671:3;41582:93;:::i;:::-;41700:2;41695:3;41691:12;41684:19;;41343:366;;;:::o;41715:419::-;41881:4;41919:2;41908:9;41904:18;41896:26;;41968:9;41962:4;41958:20;41954:1;41943:9;41939:17;41932:47;41996:131;42122:4;41996:131;:::i;:::-;41988:139;;41715:419;;;:::o;42140:167::-;42280:19;42276:1;42268:6;42264:14;42257:43;42140:167;:::o;42313:366::-;42455:3;42476:67;42540:2;42535:3;42476:67;:::i;:::-;42469:74;;42552:93;42641:3;42552:93;:::i;:::-;42670:2;42665:3;42661:12;42654:19;;42313:366;;;:::o;42685:419::-;42851:4;42889:2;42878:9;42874:18;42866:26;;42938:9;42932:4;42928:20;42924:1;42913:9;42909:17;42902:47;42966:131;43092:4;42966:131;:::i;:::-;42958:139;;42685:419;;;:::o;43110:177::-;43250:29;43246:1;43238:6;43234:14;43227:53;43110:177;:::o;43293:366::-;43435:3;43456:67;43520:2;43515:3;43456:67;:::i;:::-;43449:74;;43532:93;43621:3;43532:93;:::i;:::-;43650:2;43645:3;43641:12;43634:19;;43293:366;;;:::o;43665:419::-;43831:4;43869:2;43858:9;43854:18;43846:26;;43918:9;43912:4;43908:20;43904:1;43893:9;43889:17;43882:47;43946:131;44072:4;43946:131;:::i;:::-;43938:139;;43665:419;;;:::o;44090:173::-;44230:25;44226:1;44218:6;44214:14;44207:49;44090:173;:::o;44269:366::-;44411:3;44432:67;44496:2;44491:3;44432:67;:::i;:::-;44425:74;;44508:93;44597:3;44508:93;:::i;:::-;44626:2;44621:3;44617:12;44610:19;;44269:366;;;:::o;44641:419::-;44807:4;44845:2;44834:9;44830:18;44822:26;;44894:9;44888:4;44884:20;44880:1;44869:9;44865:17;44858:47;44922:131;45048:4;44922:131;:::i;:::-;44914:139;;44641:419;;;:::o;45066:171::-;45105:3;45128:24;45146:5;45128:24;:::i;:::-;45119:33;;45174:4;45167:5;45164:15;45161:41;;45182:18;;:::i;:::-;45161:41;45229:1;45222:5;45218:13;45211:20;;45066:171;;;:::o;45243:163::-;45383:15;45379:1;45371:6;45367:14;45360:39;45243:163;:::o;45412:366::-;45554:3;45575:67;45639:2;45634:3;45575:67;:::i;:::-;45568:74;;45651:93;45740:3;45651:93;:::i;:::-;45769:2;45764:3;45760:12;45753:19;;45412:366;;;:::o;45784:419::-;45950:4;45988:2;45977:9;45973:18;45965:26;;46037:9;46031:4;46027:20;46023:1;46012:9;46008:17;46001:47;46065:131;46191:4;46065:131;:::i;:::-;46057:139;;45784:419;;;:::o;46209:435::-;46389:3;46411:95;46502:3;46493:6;46411:95;:::i;:::-;46404:102;;46523:95;46614:3;46605:6;46523:95;:::i;:::-;46516:102;;46635:3;46628:10;;46209:435;;;;;:::o;46650:230::-;46790:34;46786:1;46778:6;46774:14;46767:58;46859:13;46854:2;46846:6;46842:15;46835:38;46650:230;:::o;46886:366::-;47028:3;47049:67;47113:2;47108:3;47049:67;:::i;:::-;47042:74;;47125:93;47214:3;47125:93;:::i;:::-;47243:2;47238:3;47234:12;47227:19;;46886:366;;;:::o;47258:419::-;47424:4;47462:2;47451:9;47447:18;47439:26;;47511:9;47505:4;47501:20;47497:1;47486:9;47482:17;47475:47;47539:131;47665:4;47539:131;:::i;:::-;47531:139;;47258:419;;;:::o;47683:239::-;47823:34;47819:1;47811:6;47807:14;47800:58;47892:22;47887:2;47879:6;47875:15;47868:47;47683:239;:::o;47928:366::-;48070:3;48091:67;48155:2;48150:3;48091:67;:::i;:::-;48084:74;;48167:93;48256:3;48167:93;:::i;:::-;48285:2;48280:3;48276:12;48269:19;;47928:366;;;:::o;48300:419::-;48466:4;48504:2;48493:9;48489:18;48481:26;;48553:9;48547:4;48543:20;48539:1;48528:9;48524:17;48517:47;48581:131;48707:4;48581:131;:::i;:::-;48573:139;;48300:419;;;:::o;48725:98::-;48776:6;48810:5;48804:12;48794:22;;48725:98;;;:::o;48829:168::-;48912:11;48946:6;48941:3;48934:19;48986:4;48981:3;48977:14;48962:29;;48829:168;;;;:::o;49003:373::-;49089:3;49117:38;49149:5;49117:38;:::i;:::-;49171:70;49234:6;49229:3;49171:70;:::i;:::-;49164:77;;49250:65;49308:6;49303:3;49296:4;49289:5;49285:16;49250:65;:::i;:::-;49340:29;49362:6;49340:29;:::i;:::-;49335:3;49331:39;49324:46;;49093:283;49003:373;;;;:::o;49382:640::-;49577:4;49615:3;49604:9;49600:19;49592:27;;49629:71;49697:1;49686:9;49682:17;49673:6;49629:71;:::i;:::-;49710:72;49778:2;49767:9;49763:18;49754:6;49710:72;:::i;:::-;49792;49860:2;49849:9;49845:18;49836:6;49792:72;:::i;:::-;49911:9;49905:4;49901:20;49896:2;49885:9;49881:18;49874:48;49939:76;50010:4;50001:6;49939:76;:::i;:::-;49931:84;;49382:640;;;;;;;:::o;50028:141::-;50084:5;50115:6;50109:13;50100:22;;50131:32;50157:5;50131:32;:::i;:::-;50028:141;;;;:::o;50175:349::-;50244:6;50293:2;50281:9;50272:7;50268:23;50264:32;50261:119;;;50299:79;;:::i;:::-;50261:119;50419:1;50444:63;50499:7;50490:6;50479:9;50475:22;50444:63;:::i;:::-;50434:73;;50390:127;50175:349;;;;:::o
Swarm Source
ipfs://b1e3dce81c0cb90aa019b523675be0c189f3bbad73af430e9a421ca5035c101a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.