Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 17492153 | 490 days ago | IN | 0 ETH | 0.07100379 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TokenRunBattlePass
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/battlepass.sol // pragma solidity ^0.8.18; pragma solidity ^0.8.18; contract TokenRunBattlePass is ERC721x { string public baseURI; uint256 public maxSupply; uint256 public maxPerWallet; uint256 public mintPrice; bool public enableTransfer; bool public enableMint; mapping(address => uint256) mintAddr; mapping(uint256 => uint256) 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 _uri, uint256 _mintPrice ) public initializerERC721A initializer { __ERC721x_init("Token Run Battle Pass", "PASS"); baseURI = _uri; enableTransfer = false; enableMint = false; maxPerWallet = 1; mintPrice = _mintPrice; } 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); } 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 baseURI; } function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_exists(_tokenId), "TOKEN NOT EXIST"); return baseURI; } function setBaseURI(string calldata _uri) external onlyOwner { baseURI = _uri; } // // =============== 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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_uri","type":"string"},{"internalType":"uint256","name":"_mintPrice","type":"uint256"}],"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":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","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":"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":"_uri","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":"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":[],"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
608060405234801561001057600080fd5b506150cb806100206000396000f3fe6080604052600436106102465760003560e01c80636817c76c11610139578063a694fc3a116100b6578063d5abeb011161007a578063d5abeb0114610859578063e58306f914610884578063e985e9c5146108ad578063f1b50c1d146108ea578063f2fde38b14610915578063f4a0a5281461093e57610246565b8063a694fc3a14610771578063ac52e6441461079a578063b1a6505f146107c3578063b88d4fde14610800578063c87b56dd1461081c57610246565b80638beaf7d7116100fd5780638beaf7d7146106a05780638da5cb5b146106c957806394d216d6146106f457806395d89b411461071d578063a22cb4651461074857610246565b80636817c76c146105b95780636c0360eb146105e457806370a082311461060f578063715018a61461064c57806372abc8b71461066357610246565b80632cba8123116101c7578063493770cc1161018b578063493770cc146104c457806355f804b3146104ed5780635d3eea91146105165780636352211e1461053f578063650b00f61461057c57610246565b80632cba8123146103ec57806340a9c8df1461042957806342842e0e1461045257806344b28d591461046e578063453c23101461049957610246565b80631249c58b1161020e5780631249c58b1461034957806318160ddd146103535780631f85e3ca1461037e57806323b872dd146103a75780632799cde0146103c357610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b357806309308e5d146102f0578063095ea7b31461032d575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d91906137ab565b610967565b60405161027f91906137f3565b60405180910390f35b34801561029457600080fd5b5061029d6109c8565b6040516102aa919061389e565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d591906138f6565b610a63565b6040516102e79190613964565b60405180910390f35b3480156102fc57600080fd5b50610317600480360381019061031291906139ab565b610aeb565b60405161032491906139fa565b60405180910390f35b61034760048036038101906103429190613a15565b610b10565b005b610351610b20565b005b34801561035f57600080fd5b50610368610c89565b60405161037591906139fa565b60405180910390f35b34801561038a57600080fd5b506103a560048036038101906103a09190613a81565b610cb2565b005b6103c160048036038101906103bc9190613aae565b610cd7565b005b3480156103cf57600080fd5b506103ea60048036038101906103e591906138f6565b610d8c565b005b3480156103f857600080fd5b50610413600480360381019061040e9190613b01565b610de0565b6040516104209190613964565b60405180910390f35b34801561043557600080fd5b50610450600480360381019061044b91906138f6565b610e22565b005b61046c60048036038101906104679190613aae565b610e76565b005b34801561047a57600080fd5b50610483610e96565b60405161049091906137f3565b60405180910390f35b3480156104a557600080fd5b506104ae610ea9565b6040516104bb91906139fa565b60405180910390f35b3480156104d057600080fd5b506104eb60048036038101906104e69190613a81565b610eaf565b005b3480156104f957600080fd5b50610514600480360381019061050f9190613ba6565b610ed4565b005b34801561052257600080fd5b5061053d600480360381019061053891906138f6565b610ef2565b005b34801561054b57600080fd5b50610566600480360381019061056191906138f6565b611030565b6040516105739190613964565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e91906138f6565b611042565b6040516105b091906139fa565b60405180910390f35b3480156105c557600080fd5b506105ce61105a565b6040516105db91906139fa565b60405180910390f35b3480156105f057600080fd5b506105f9611060565b604051610606919061389e565b60405180910390f35b34801561061b57600080fd5b5061063660048036038101906106319190613bf3565b6110ee565b60405161064391906139fa565b60405180910390f35b34801561065857600080fd5b506106616111af565b005b34801561066f57600080fd5b5061068a600480360381019061068591906138f6565b6111c3565b60405161069791906137f3565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c29190613d50565b6111e2565b005b3480156106d557600080fd5b506106de611500565b6040516106eb9190613964565b60405180910390f35b34801561070057600080fd5b5061071b600480360381019061071691906139ab565b61152a565b005b34801561072957600080fd5b50610732611580565b60405161073f919061389e565b60405180910390f35b34801561075457600080fd5b5061076f600480360381019061076a9190613dac565b61161b565b005b34801561077d57600080fd5b50610798600480360381019061079391906138f6565b61172f565b005b3480156107a657600080fd5b506107c160048036038101906107bc9190613e98565b611864565b005b3480156107cf57600080fd5b506107ea60048036038101906107e59190613bf3565b611981565b6040516107f791906137f3565b60405180910390f35b61081a60048036038101906108159190613fba565b6119a1565b005b34801561082857600080fd5b50610843600480360381019061083e91906138f6565b611a58565b604051610850919061389e565b60405180910390f35b34801561086557600080fd5b5061086e611b34565b60405161087b91906139fa565b60405180910390f35b34801561089057600080fd5b506108ab60048036038101906108a69190613a15565b611b3a565b005b3480156108b957600080fd5b506108d460048036038101906108cf919061403d565b611b50565b6040516108e191906137f3565b60405180910390f35b3480156108f657600080fd5b506108ff611bed565b60405161090c91906137f3565b60405180910390f35b34801561092157600080fd5b5061093c60048036038101906109379190613bf3565b611c00565b005b34801561094a57600080fd5b50610965600480360381019061096091906138f6565b611c83565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109c157506109c082611c95565b5b9050919050565b60606109d2611d27565b60020180546109e0906140ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0c906140ac565b8015610a595780601f10610a2e57610100808354040283529160200191610a59565b820191906000526020600020905b815481529060010190602001808311610a3c57829003601f168201915b5050505050905090565b6000610a6e82611d54565b610aa4576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610aac611d27565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610b1c82826001611dc5565b5050565b606d60019054906101000a900460ff16610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6690614129565b60405180910390fd5b606c54341015610bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab90614195565b60405180910390fd5b606b54606e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610c37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2e90614201565b60405180910390fd5b6001606e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c87336001611f1a565b565b6000610c93611f28565b610c9b611d27565b60010154610ca7611d27565b600001540303905090565b610cba611f31565b80606d60016101000a81548160ff02191690831515021790555050565b606d60009054906101000a900460ff16610d26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1d9061426d565b60405180910390fd5b6000606f60008381526020019081526020016000205414610d7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d73906142d9565b60405180910390fd5b610d87838383611faf565b505050565b610d9581611d54565b610dd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dcb90614345565b60405180910390fd5b610ddd81612007565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610e2b81611d54565b610e6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6190614345565b60405180910390fd5b610e7381612273565b50565b610e91838383604051806020016040528060008152506119a1565b505050565b606d60019054906101000a900460ff1681565b606b5481565b610eb7611f31565b80606d60006101000a81548160ff02191690831515021790555050565b610edc611f31565b818160699182610eed92919061451c565b505050565b610efb81611030565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5f90614638565b60405180910390fd5b6000606f60008381526020019081526020016000205414610fbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb5906146a4565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c28233834260405161102494939291906146c4565b60405180910390a15050565b600061103b8261264e565b9050919050565b60666020528060005260406000206000915090505481565b606c5481565b6069805461106d906140ac565b80601f0160208091040260200160405190810160405280929190818152602001828054611099906140ac565b80156110e65780601f106110bb576101008083540402835291602001916110e6565b820191906000526020600020905b8154815290600101906020018083116110c957829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611155576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff611166611d27565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6111b7611f31565b6111c16000612761565b565b6000806066600084815260200190815260200160002054149050919050565b6111ea612827565b60000160019054906101000a900460ff1661121e57611207612827565b60000160009054906101000a900460ff1615611227565b611226612854565b5b611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d9061477b565b60405180910390fd5b6000611270612827565b60000160019054906101000a900460ff1615905080156112d3576001611294612827565b60000160016101000a81548160ff02191690831515021790555060016112b8612827565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff161590508080156113045750600160008054906101000a900460ff1660ff16105b8061133157506113133061286b565b1580156113305750600160008054906101000a900460ff1660ff16145b5b611370576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113679061480d565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156113ad576001600060016101000a81548160ff0219169083151502179055505b6114216040518060400160405280601581526020017f546f6b656e2052756e20426174746c65205061737300000000000000000000008152506040518060400160405280600481526020017f504153530000000000000000000000000000000000000000000000000000000081525061288e565b8360699081611430919061482d565b506000606d60006101000a81548160ff0219169083151502179055506000606d60016101000a81548160ff0219169083151502179055506001606b8190555082606c8190555080156114cf5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516114c69190614947565b60405180910390a15b5080156114fb5760006114e0612827565b60000160016101000a81548160ff0219169083151502179055505b505050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61153382611d54565b611572576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156990614345565b60405180910390fd5b61157c82826128f3565b5050565b606061158a611d27565b6003018054611598906140ac565b80601f01602080910402602001604051908101604052809291908181526020018280546115c4906140ac565b80156116115780601f106115e657610100808354040283529160200191611611565b820191906000526020600020905b8154815290600101906020018083116115f457829003601f168201915b5050505050905090565b80611624611d27565b6007016000611631612cd0565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166116de612cd0565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161172391906137f3565b60405180910390a35050565b61173881611030565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179c90614638565b60405180910390fd5b6000606f600083815260200190815260200160002054146117fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f2906146a4565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f60008581526020019081526020016000205460405161185993929190614962565b60405180910390a150565b61186c611f31565b8181905084849050146118b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ab906149e5565b60405180910390fd5b60005b8484905081101561197a578282828181106118d5576118d4614a05565b5b90506020020160208101906118ea9190613a81565b6065600087878581811061190157611900614a05565b5b90506020020160208101906119169190613bf3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061197290614a63565b9150506118b7565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606d60009054906101000a900460ff166119f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e79061426d565b60405180910390fd5b6000606f60008481526020019081526020016000205414611a46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3d906142d9565b60405180910390fd5b611a5284848484612cd8565b50505050565b6060611a6382611d54565b611aa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9990614af7565b60405180910390fd5b60698054611aaf906140ac565b80601f0160208091040260200160405190810160405280929190818152602001828054611adb906140ac565b8015611b285780601f10611afd57610100808354040283529160200191611b28565b820191906000526020600020905b815481529060010190602001808311611b0b57829003601f168201915b50505050509050919050565b606a5481565b611b42611f31565b611b4c8282611f1a565b5050565b6000611b5a611d27565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606d60009054906101000a900460ff1681565b611c08611f31565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6e90614b89565b60405180910390fd5b611c8081612761565b50565b611c8b611f31565b80606c8190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611cf057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611d205750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611d5f611f28565b11158015611d775750611d70611d27565b6000015482105b8015611dbe575060007c0100000000000000000000000000000000000000000000000000000000611da6611d27565b60040160008581526020019081526020016000205416145b9050919050565b6000611dd083611030565b90508115611e5b578073ffffffffffffffffffffffffffffffffffffffff16611df7612cd0565b73ffffffffffffffffffffffffffffffffffffffff1614611e5a57611e2381611e1e612cd0565b611b50565b611e59576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83611e64611d27565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b611f248282612d32565b5050565b60006001905090565b611f39612f12565b73ffffffffffffffffffffffffffffffffffffffff16611f57611500565b73ffffffffffffffffffffffffffffffffffffffff1614611fad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa490614bf5565b60405180910390fd5b565b611fb8816111c3565b611ff7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fee90614c61565b60405180910390fd5b612002838383612f1a565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612093576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161208a90614ccd565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414612126576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211d90614d39565b60405180910390fd5b6000600160666000848152602001908152602001600020546121489190614d59565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061222690614a63565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166122ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f690614ccd565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161238e90614dd9565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461252157600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612586565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000848152602001908152602001600020600081548092919061260090614df9565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b600081612659611f28565b1161272a57612666611d27565b600401600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036127295760008103612724576126b4611d27565b6000015482106126f0576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6126f9611d27565b6004016000836001900393508381526020019081526020016000205490506000810361275c576126f1565b61275c565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166128dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d490614e94565b60405180910390fd5b6128e78282613272565b6128ef6132d8565b5050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612980576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297790614ccd565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612a18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a0f90614f00565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612ba257600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612c07565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612c8190614df9565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612ce1826111c3565b612d20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1790614c61565b60405180910390fd5b612d2c84848484613331565b50505050565b6000612d3c611d27565b60000154905060008203612d7c576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d8960008483856133a4565b600160406001901b178202612d9c611d27565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612e0983612dfa60008660006133aa565b612e03856133d2565b176133e2565b612e11611d27565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612eb357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612e78565b5060008203612eee576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80612ef7611d27565b600001819055505050612f0d600084838561340d565b505050565b600033905090565b6000612f258261264e565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612f8c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080612f9884613413565b91509150612fae8187612fa9612cd0565b613443565b612ffa57612fc386612fbe612cd0565b611b50565b612ff9576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613060576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61306d86868660016133a4565b801561307857600082555b613080611d27565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460019003919050819055506130d7611d27565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550613158856131348888876133aa565b7c0200000000000000000000000000000000000000000000000000000000176133e2565b613160611d27565b60040160008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361320257600060018501905060006131b1611d27565b60040160008381526020019081526020016000205403613200576131d3611d27565b6000015481146131ff57836131e6611d27565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461326a868686600161340d565b505050505050565b61327a612827565b60000160019054906101000a900460ff166132ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132c190614f92565b60405180910390fd5b6132d48282613487565b5050565b600060019054906101000a900460ff16613327576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161331e90614e94565b60405180910390fd5b61332f61352c565b565b61333c848484610cd7565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461339e5761336784848484613585565b61339d576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b50505050565b60008060e883901c905060e86133c18686846136d5565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000806000613420611d27565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b61348f612827565b60000160019054906101000a900460ff166134df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134d690614f92565b60405180910390fd5b816134e8611d27565b60020190816134f7919061482d565b5080613501611d27565b6003019081613510919061482d565b50613519611f28565b613521611d27565b600001819055505050565b600060019054906101000a900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161357290614e94565b60405180910390fd5b6135836136de565b565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026135ab612cd0565b8786866040518563ffffffff1660e01b81526004016135cd9493929190615007565b6020604051808303816000875af192505050801561360957506040513d601f19601f820116820180604052508101906136069190615068565b60015b613682573d8060008114613639576040519150601f19603f3d011682016040523d82523d6000602084013e61363e565b606091505b50600081510361367a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b600060019054906101000a900460ff1661372d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161372490614e94565b60405180910390fd5b61373d613738612f12565b612761565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61378881613753565b811461379357600080fd5b50565b6000813590506137a58161377f565b92915050565b6000602082840312156137c1576137c0613749565b5b60006137cf84828501613796565b91505092915050565b60008115159050919050565b6137ed816137d8565b82525050565b600060208201905061380860008301846137e4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561384857808201518184015260208101905061382d565b60008484015250505050565b6000601f19601f8301169050919050565b60006138708261380e565b61387a8185613819565b935061388a81856020860161382a565b61389381613854565b840191505092915050565b600060208201905081810360008301526138b88184613865565b905092915050565b6000819050919050565b6138d3816138c0565b81146138de57600080fd5b50565b6000813590506138f0816138ca565b92915050565b60006020828403121561390c5761390b613749565b5b600061391a848285016138e1565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061394e82613923565b9050919050565b61395e81613943565b82525050565b60006020820190506139796000830184613955565b92915050565b61398881613943565b811461399357600080fd5b50565b6000813590506139a58161397f565b92915050565b600080604083850312156139c2576139c1613749565b5b60006139d0858286016138e1565b92505060206139e185828601613996565b9150509250929050565b6139f4816138c0565b82525050565b6000602082019050613a0f60008301846139eb565b92915050565b60008060408385031215613a2c57613a2b613749565b5b6000613a3a85828601613996565b9250506020613a4b858286016138e1565b9150509250929050565b613a5e816137d8565b8114613a6957600080fd5b50565b600081359050613a7b81613a55565b92915050565b600060208284031215613a9757613a96613749565b5b6000613aa584828501613a6c565b91505092915050565b600080600060608486031215613ac757613ac6613749565b5b6000613ad586828701613996565b9350506020613ae686828701613996565b9250506040613af7868287016138e1565b9150509250925092565b60008060408385031215613b1857613b17613749565b5b6000613b26858286016138e1565b9250506020613b37858286016138e1565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613b6657613b65613b41565b5b8235905067ffffffffffffffff811115613b8357613b82613b46565b5b602083019150836001820283011115613b9f57613b9e613b4b565b5b9250929050565b60008060208385031215613bbd57613bbc613749565b5b600083013567ffffffffffffffff811115613bdb57613bda61374e565b5b613be785828601613b50565b92509250509250929050565b600060208284031215613c0957613c08613749565b5b6000613c1784828501613996565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613c5d82613854565b810181811067ffffffffffffffff82111715613c7c57613c7b613c25565b5b80604052505050565b6000613c8f61373f565b9050613c9b8282613c54565b919050565b600067ffffffffffffffff821115613cbb57613cba613c25565b5b613cc482613854565b9050602081019050919050565b82818337600083830152505050565b6000613cf3613cee84613ca0565b613c85565b905082815260208101848484011115613d0f57613d0e613c20565b5b613d1a848285613cd1565b509392505050565b600082601f830112613d3757613d36613b41565b5b8135613d47848260208601613ce0565b91505092915050565b60008060408385031215613d6757613d66613749565b5b600083013567ffffffffffffffff811115613d8557613d8461374e565b5b613d9185828601613d22565b9250506020613da2858286016138e1565b9150509250929050565b60008060408385031215613dc357613dc2613749565b5b6000613dd185828601613996565b9250506020613de285828601613a6c565b9150509250929050565b60008083601f840112613e0257613e01613b41565b5b8235905067ffffffffffffffff811115613e1f57613e1e613b46565b5b602083019150836020820283011115613e3b57613e3a613b4b565b5b9250929050565b60008083601f840112613e5857613e57613b41565b5b8235905067ffffffffffffffff811115613e7557613e74613b46565b5b602083019150836020820283011115613e9157613e90613b4b565b5b9250929050565b60008060008060408587031215613eb257613eb1613749565b5b600085013567ffffffffffffffff811115613ed057613ecf61374e565b5b613edc87828801613dec565b9450945050602085013567ffffffffffffffff811115613eff57613efe61374e565b5b613f0b87828801613e42565b925092505092959194509250565b600067ffffffffffffffff821115613f3457613f33613c25565b5b613f3d82613854565b9050602081019050919050565b6000613f5d613f5884613f19565b613c85565b905082815260208101848484011115613f7957613f78613c20565b5b613f84848285613cd1565b509392505050565b600082601f830112613fa157613fa0613b41565b5b8135613fb1848260208601613f4a565b91505092915050565b60008060008060808587031215613fd457613fd3613749565b5b6000613fe287828801613996565b9450506020613ff387828801613996565b9350506040614004878288016138e1565b925050606085013567ffffffffffffffff8111156140255761402461374e565b5b61403187828801613f8c565b91505092959194509250565b6000806040838503121561405457614053613749565b5b600061406285828601613996565b925050602061407385828601613996565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806140c457607f821691505b6020821081036140d7576140d661407d565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b6000614113601083613819565b915061411e826140dd565b602082019050919050565b6000602082019050818103600083015261414281614106565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b600061417f601283613819565b915061418a82614149565b602082019050919050565b600060208201905081810360008301526141ae81614172565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006141eb601383613819565b91506141f6826141b5565b602082019050919050565b6000602082019050818103600083015261421a816141de565b9050919050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b6000614257601483613819565b915061426282614221565b602082019050919050565b600060208201905081810360008301526142868161424a565b9050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b60006142c3601c83613819565b91506142ce8261428d565b602082019050919050565b600060208201905081810360008301526142f2816142b6565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b600061432f600c83613819565b915061433a826142f9565b602082019050919050565b6000602082019050818103600083015261435e81614322565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026143d27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614395565b6143dc8683614395565b95508019841693508086168417925050509392505050565b6000819050919050565b600061441961441461440f846138c0565b6143f4565b6138c0565b9050919050565b6000819050919050565b614433836143fe565b61444761443f82614420565b8484546143a2565b825550505050565b600090565b61445c61444f565b61446781848461442a565b505050565b5b8181101561448b57614480600082614454565b60018101905061446d565b5050565b601f8211156144d0576144a181614370565b6144aa84614385565b810160208510156144b9578190505b6144cd6144c585614385565b83018261446c565b50505b505050565b600082821c905092915050565b60006144f3600019846008026144d5565b1980831691505092915050565b600061450c83836144e2565b9150826002028217905092915050565b6145268383614365565b67ffffffffffffffff81111561453f5761453e613c25565b5b61454982546140ac565b61455482828561448f565b6000601f8311600181146145835760008415614571578287013590505b61457b8582614500565b8655506145e3565b601f19841661459186614370565b60005b828110156145b957848901358255600182019150602085019450602081019050614594565b868310156145d657848901356145d2601f8916826144e2565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b6000614622601483613819565b915061462d826145ec565b602082019050919050565b6000602082019050818103600083015261465181614615565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b600061468e600f83613819565b915061469982614658565b602082019050919050565b600060208201905081810360008301526146bd81614681565b9050919050565b60006080820190506146d960008301876139eb565b6146e66020830186613955565b6146f360408301856139eb565b61470060608301846139eb565b95945050505050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b6000614765603783613819565b915061477082614709565b604082019050919050565b6000602082019050818103600083015261479481614758565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006147f7602e83613819565b91506148028261479b565b604082019050919050565b60006020820190508181036000830152614826816147ea565b9050919050565b6148368261380e565b67ffffffffffffffff81111561484f5761484e613c25565b5b61485982546140ac565b61486482828561448f565b600060209050601f8311600181146148975760008415614885578287015190505b61488f8582614500565b8655506148f7565b601f1984166148a586614370565b60005b828110156148cd578489015182556001820191506020850194506020810190506148a8565b868310156148ea57848901516148e6601f8916826144e2565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b600061493161492c614927846148ff565b6143f4565b614909565b9050919050565b61494181614916565b82525050565b600060208201905061495c6000830184614938565b92915050565b600060608201905061497760008301866139eb565b6149846020830185613955565b61499160408301846139eb565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b60006149cf600783613819565b91506149da82614999565b602082019050919050565b600060208201905081810360008301526149fe816149c2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a6e826138c0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614aa057614a9f614a34565b5b600182019050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614ae1600f83613819565b9150614aec82614aab565b602082019050919050565b60006020820190508181036000830152614b1081614ad4565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614b73602683613819565b9150614b7e82614b17565b604082019050919050565b60006020820190508181036000830152614ba281614b66565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614bdf602083613819565b9150614bea82614ba9565b602082019050919050565b60006020820190508181036000830152614c0e81614bd2565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b6000614c4b600f83613819565b9150614c5682614c15565b602082019050919050565b60006020820190508181036000830152614c7a81614c3e565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b6000614cb7601183613819565b9150614cc282614c81565b602082019050919050565b60006020820190508181036000830152614ce681614caa565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b6000614d23601b83613819565b9150614d2e82614ced565b602082019050919050565b60006020820190508181036000830152614d5281614d16565b9050919050565b6000614d64826138c0565b9150614d6f836138c0565b9250828201905080821115614d8757614d86614a34565b5b92915050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b6000614dc3601783613819565b9150614dce82614d8d565b602082019050919050565b60006020820190508181036000830152614df281614db6565b9050919050565b6000614e04826138c0565b915060008203614e1757614e16614a34565b5b600182039050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000614e7e602b83613819565b9150614e8982614e22565b604082019050919050565b60006020820190508181036000830152614ead81614e71565b9050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b6000614eea600d83613819565b9150614ef582614eb4565b602082019050919050565b60006020820190508181036000830152614f1981614edd565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000614f7c603483613819565b9150614f8782614f20565b604082019050919050565b60006020820190508181036000830152614fab81614f6f565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614fd982614fb2565b614fe38185614fbd565b9350614ff381856020860161382a565b614ffc81613854565b840191505092915050565b600060808201905061501c6000830187613955565b6150296020830186613955565b61503660408301856139eb565b81810360608301526150488184614fce565b905095945050505050565b6000815190506150628161377f565b92915050565b60006020828403121561507e5761507d613749565b5b600061508c84828501615053565b9150509291505056fea26469706673582212209721d7bfbcd8e5cd62de2691f6a2a8a01fe7c45a27a69ed2ddb20ff7c16b783364736f6c63430008120033
Deployed Bytecode
0x6080604052600436106102465760003560e01c80636817c76c11610139578063a694fc3a116100b6578063d5abeb011161007a578063d5abeb0114610859578063e58306f914610884578063e985e9c5146108ad578063f1b50c1d146108ea578063f2fde38b14610915578063f4a0a5281461093e57610246565b8063a694fc3a14610771578063ac52e6441461079a578063b1a6505f146107c3578063b88d4fde14610800578063c87b56dd1461081c57610246565b80638beaf7d7116100fd5780638beaf7d7146106a05780638da5cb5b146106c957806394d216d6146106f457806395d89b411461071d578063a22cb4651461074857610246565b80636817c76c146105b95780636c0360eb146105e457806370a082311461060f578063715018a61461064c57806372abc8b71461066357610246565b80632cba8123116101c7578063493770cc1161018b578063493770cc146104c457806355f804b3146104ed5780635d3eea91146105165780636352211e1461053f578063650b00f61461057c57610246565b80632cba8123146103ec57806340a9c8df1461042957806342842e0e1461045257806344b28d591461046e578063453c23101461049957610246565b80631249c58b1161020e5780631249c58b1461034957806318160ddd146103535780631f85e3ca1461037e57806323b872dd146103a75780632799cde0146103c357610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b357806309308e5d146102f0578063095ea7b31461032d575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d91906137ab565b610967565b60405161027f91906137f3565b60405180910390f35b34801561029457600080fd5b5061029d6109c8565b6040516102aa919061389e565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d591906138f6565b610a63565b6040516102e79190613964565b60405180910390f35b3480156102fc57600080fd5b50610317600480360381019061031291906139ab565b610aeb565b60405161032491906139fa565b60405180910390f35b61034760048036038101906103429190613a15565b610b10565b005b610351610b20565b005b34801561035f57600080fd5b50610368610c89565b60405161037591906139fa565b60405180910390f35b34801561038a57600080fd5b506103a560048036038101906103a09190613a81565b610cb2565b005b6103c160048036038101906103bc9190613aae565b610cd7565b005b3480156103cf57600080fd5b506103ea60048036038101906103e591906138f6565b610d8c565b005b3480156103f857600080fd5b50610413600480360381019061040e9190613b01565b610de0565b6040516104209190613964565b60405180910390f35b34801561043557600080fd5b50610450600480360381019061044b91906138f6565b610e22565b005b61046c60048036038101906104679190613aae565b610e76565b005b34801561047a57600080fd5b50610483610e96565b60405161049091906137f3565b60405180910390f35b3480156104a557600080fd5b506104ae610ea9565b6040516104bb91906139fa565b60405180910390f35b3480156104d057600080fd5b506104eb60048036038101906104e69190613a81565b610eaf565b005b3480156104f957600080fd5b50610514600480360381019061050f9190613ba6565b610ed4565b005b34801561052257600080fd5b5061053d600480360381019061053891906138f6565b610ef2565b005b34801561054b57600080fd5b50610566600480360381019061056191906138f6565b611030565b6040516105739190613964565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e91906138f6565b611042565b6040516105b091906139fa565b60405180910390f35b3480156105c557600080fd5b506105ce61105a565b6040516105db91906139fa565b60405180910390f35b3480156105f057600080fd5b506105f9611060565b604051610606919061389e565b60405180910390f35b34801561061b57600080fd5b5061063660048036038101906106319190613bf3565b6110ee565b60405161064391906139fa565b60405180910390f35b34801561065857600080fd5b506106616111af565b005b34801561066f57600080fd5b5061068a600480360381019061068591906138f6565b6111c3565b60405161069791906137f3565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c29190613d50565b6111e2565b005b3480156106d557600080fd5b506106de611500565b6040516106eb9190613964565b60405180910390f35b34801561070057600080fd5b5061071b600480360381019061071691906139ab565b61152a565b005b34801561072957600080fd5b50610732611580565b60405161073f919061389e565b60405180910390f35b34801561075457600080fd5b5061076f600480360381019061076a9190613dac565b61161b565b005b34801561077d57600080fd5b50610798600480360381019061079391906138f6565b61172f565b005b3480156107a657600080fd5b506107c160048036038101906107bc9190613e98565b611864565b005b3480156107cf57600080fd5b506107ea60048036038101906107e59190613bf3565b611981565b6040516107f791906137f3565b60405180910390f35b61081a60048036038101906108159190613fba565b6119a1565b005b34801561082857600080fd5b50610843600480360381019061083e91906138f6565b611a58565b604051610850919061389e565b60405180910390f35b34801561086557600080fd5b5061086e611b34565b60405161087b91906139fa565b60405180910390f35b34801561089057600080fd5b506108ab60048036038101906108a69190613a15565b611b3a565b005b3480156108b957600080fd5b506108d460048036038101906108cf919061403d565b611b50565b6040516108e191906137f3565b60405180910390f35b3480156108f657600080fd5b506108ff611bed565b60405161090c91906137f3565b60405180910390f35b34801561092157600080fd5b5061093c60048036038101906109379190613bf3565b611c00565b005b34801561094a57600080fd5b50610965600480360381019061096091906138f6565b611c83565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109c157506109c082611c95565b5b9050919050565b60606109d2611d27565b60020180546109e0906140ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0c906140ac565b8015610a595780601f10610a2e57610100808354040283529160200191610a59565b820191906000526020600020905b815481529060010190602001808311610a3c57829003601f168201915b5050505050905090565b6000610a6e82611d54565b610aa4576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610aac611d27565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610b1c82826001611dc5565b5050565b606d60019054906101000a900460ff16610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6690614129565b60405180910390fd5b606c54341015610bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab90614195565b60405180910390fd5b606b54606e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610c37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2e90614201565b60405180910390fd5b6001606e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c87336001611f1a565b565b6000610c93611f28565b610c9b611d27565b60010154610ca7611d27565b600001540303905090565b610cba611f31565b80606d60016101000a81548160ff02191690831515021790555050565b606d60009054906101000a900460ff16610d26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1d9061426d565b60405180910390fd5b6000606f60008381526020019081526020016000205414610d7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d73906142d9565b60405180910390fd5b610d87838383611faf565b505050565b610d9581611d54565b610dd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dcb90614345565b60405180910390fd5b610ddd81612007565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610e2b81611d54565b610e6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6190614345565b60405180910390fd5b610e7381612273565b50565b610e91838383604051806020016040528060008152506119a1565b505050565b606d60019054906101000a900460ff1681565b606b5481565b610eb7611f31565b80606d60006101000a81548160ff02191690831515021790555050565b610edc611f31565b818160699182610eed92919061451c565b505050565b610efb81611030565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f5f90614638565b60405180910390fd5b6000606f60008381526020019081526020016000205414610fbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb5906146a4565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c28233834260405161102494939291906146c4565b60405180910390a15050565b600061103b8261264e565b9050919050565b60666020528060005260406000206000915090505481565b606c5481565b6069805461106d906140ac565b80601f0160208091040260200160405190810160405280929190818152602001828054611099906140ac565b80156110e65780601f106110bb576101008083540402835291602001916110e6565b820191906000526020600020905b8154815290600101906020018083116110c957829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611155576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff611166611d27565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6111b7611f31565b6111c16000612761565b565b6000806066600084815260200190815260200160002054149050919050565b6111ea612827565b60000160019054906101000a900460ff1661121e57611207612827565b60000160009054906101000a900460ff1615611227565b611226612854565b5b611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d9061477b565b60405180910390fd5b6000611270612827565b60000160019054906101000a900460ff1615905080156112d3576001611294612827565b60000160016101000a81548160ff02191690831515021790555060016112b8612827565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff161590508080156113045750600160008054906101000a900460ff1660ff16105b8061133157506113133061286b565b1580156113305750600160008054906101000a900460ff1660ff16145b5b611370576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113679061480d565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156113ad576001600060016101000a81548160ff0219169083151502179055505b6114216040518060400160405280601581526020017f546f6b656e2052756e20426174746c65205061737300000000000000000000008152506040518060400160405280600481526020017f504153530000000000000000000000000000000000000000000000000000000081525061288e565b8360699081611430919061482d565b506000606d60006101000a81548160ff0219169083151502179055506000606d60016101000a81548160ff0219169083151502179055506001606b8190555082606c8190555080156114cf5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516114c69190614947565b60405180910390a15b5080156114fb5760006114e0612827565b60000160016101000a81548160ff0219169083151502179055505b505050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61153382611d54565b611572576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156990614345565b60405180910390fd5b61157c82826128f3565b5050565b606061158a611d27565b6003018054611598906140ac565b80601f01602080910402602001604051908101604052809291908181526020018280546115c4906140ac565b80156116115780601f106115e657610100808354040283529160200191611611565b820191906000526020600020905b8154815290600101906020018083116115f457829003601f168201915b5050505050905090565b80611624611d27565b6007016000611631612cd0565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166116de612cd0565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161172391906137f3565b60405180910390a35050565b61173881611030565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179c90614638565b60405180910390fd5b6000606f600083815260200190815260200160002054146117fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f2906146a4565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f60008581526020019081526020016000205460405161185993929190614962565b60405180910390a150565b61186c611f31565b8181905084849050146118b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ab906149e5565b60405180910390fd5b60005b8484905081101561197a578282828181106118d5576118d4614a05565b5b90506020020160208101906118ea9190613a81565b6065600087878581811061190157611900614a05565b5b90506020020160208101906119169190613bf3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061197290614a63565b9150506118b7565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606d60009054906101000a900460ff166119f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e79061426d565b60405180910390fd5b6000606f60008481526020019081526020016000205414611a46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3d906142d9565b60405180910390fd5b611a5284848484612cd8565b50505050565b6060611a6382611d54565b611aa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9990614af7565b60405180910390fd5b60698054611aaf906140ac565b80601f0160208091040260200160405190810160405280929190818152602001828054611adb906140ac565b8015611b285780601f10611afd57610100808354040283529160200191611b28565b820191906000526020600020905b815481529060010190602001808311611b0b57829003601f168201915b50505050509050919050565b606a5481565b611b42611f31565b611b4c8282611f1a565b5050565b6000611b5a611d27565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606d60009054906101000a900460ff1681565b611c08611f31565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6e90614b89565b60405180910390fd5b611c8081612761565b50565b611c8b611f31565b80606c8190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611cf057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611d205750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611d5f611f28565b11158015611d775750611d70611d27565b6000015482105b8015611dbe575060007c0100000000000000000000000000000000000000000000000000000000611da6611d27565b60040160008581526020019081526020016000205416145b9050919050565b6000611dd083611030565b90508115611e5b578073ffffffffffffffffffffffffffffffffffffffff16611df7612cd0565b73ffffffffffffffffffffffffffffffffffffffff1614611e5a57611e2381611e1e612cd0565b611b50565b611e59576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83611e64611d27565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b611f248282612d32565b5050565b60006001905090565b611f39612f12565b73ffffffffffffffffffffffffffffffffffffffff16611f57611500565b73ffffffffffffffffffffffffffffffffffffffff1614611fad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa490614bf5565b60405180910390fd5b565b611fb8816111c3565b611ff7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fee90614c61565b60405180910390fd5b612002838383612f1a565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612093576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161208a90614ccd565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414612126576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211d90614d39565b60405180910390fd5b6000600160666000848152602001908152602001600020546121489190614d59565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061222690614a63565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166122ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f690614ccd565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161238e90614dd9565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461252157600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612586565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000848152602001908152602001600020600081548092919061260090614df9565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b600081612659611f28565b1161272a57612666611d27565b600401600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036127295760008103612724576126b4611d27565b6000015482106126f0576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6126f9611d27565b6004016000836001900393508381526020019081526020016000205490506000810361275c576126f1565b61275c565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166128dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d490614e94565b60405180910390fd5b6128e78282613272565b6128ef6132d8565b5050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612980576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297790614ccd565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612a18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a0f90614f00565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612ba257600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612c07565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612c8190614df9565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612ce1826111c3565b612d20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1790614c61565b60405180910390fd5b612d2c84848484613331565b50505050565b6000612d3c611d27565b60000154905060008203612d7c576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d8960008483856133a4565b600160406001901b178202612d9c611d27565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612e0983612dfa60008660006133aa565b612e03856133d2565b176133e2565b612e11611d27565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612eb357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612e78565b5060008203612eee576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80612ef7611d27565b600001819055505050612f0d600084838561340d565b505050565b600033905090565b6000612f258261264e565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612f8c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080612f9884613413565b91509150612fae8187612fa9612cd0565b613443565b612ffa57612fc386612fbe612cd0565b611b50565b612ff9576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613060576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61306d86868660016133a4565b801561307857600082555b613080611d27565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460019003919050819055506130d7611d27565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550613158856131348888876133aa565b7c0200000000000000000000000000000000000000000000000000000000176133e2565b613160611d27565b60040160008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361320257600060018501905060006131b1611d27565b60040160008381526020019081526020016000205403613200576131d3611d27565b6000015481146131ff57836131e6611d27565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461326a868686600161340d565b505050505050565b61327a612827565b60000160019054906101000a900460ff166132ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132c190614f92565b60405180910390fd5b6132d48282613487565b5050565b600060019054906101000a900460ff16613327576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161331e90614e94565b60405180910390fd5b61332f61352c565b565b61333c848484610cd7565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461339e5761336784848484613585565b61339d576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b50505050565b60008060e883901c905060e86133c18686846136d5565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000806000613420611d27565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b61348f612827565b60000160019054906101000a900460ff166134df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134d690614f92565b60405180910390fd5b816134e8611d27565b60020190816134f7919061482d565b5080613501611d27565b6003019081613510919061482d565b50613519611f28565b613521611d27565b600001819055505050565b600060019054906101000a900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161357290614e94565b60405180910390fd5b6135836136de565b565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026135ab612cd0565b8786866040518563ffffffff1660e01b81526004016135cd9493929190615007565b6020604051808303816000875af192505050801561360957506040513d601f19601f820116820180604052508101906136069190615068565b60015b613682573d8060008114613639576040519150601f19603f3d011682016040523d82523d6000602084013e61363e565b606091505b50600081510361367a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b600060019054906101000a900460ff1661372d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161372490614e94565b60405180910390fd5b61373d613738612f12565b612761565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61378881613753565b811461379357600080fd5b50565b6000813590506137a58161377f565b92915050565b6000602082840312156137c1576137c0613749565b5b60006137cf84828501613796565b91505092915050565b60008115159050919050565b6137ed816137d8565b82525050565b600060208201905061380860008301846137e4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561384857808201518184015260208101905061382d565b60008484015250505050565b6000601f19601f8301169050919050565b60006138708261380e565b61387a8185613819565b935061388a81856020860161382a565b61389381613854565b840191505092915050565b600060208201905081810360008301526138b88184613865565b905092915050565b6000819050919050565b6138d3816138c0565b81146138de57600080fd5b50565b6000813590506138f0816138ca565b92915050565b60006020828403121561390c5761390b613749565b5b600061391a848285016138e1565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061394e82613923565b9050919050565b61395e81613943565b82525050565b60006020820190506139796000830184613955565b92915050565b61398881613943565b811461399357600080fd5b50565b6000813590506139a58161397f565b92915050565b600080604083850312156139c2576139c1613749565b5b60006139d0858286016138e1565b92505060206139e185828601613996565b9150509250929050565b6139f4816138c0565b82525050565b6000602082019050613a0f60008301846139eb565b92915050565b60008060408385031215613a2c57613a2b613749565b5b6000613a3a85828601613996565b9250506020613a4b858286016138e1565b9150509250929050565b613a5e816137d8565b8114613a6957600080fd5b50565b600081359050613a7b81613a55565b92915050565b600060208284031215613a9757613a96613749565b5b6000613aa584828501613a6c565b91505092915050565b600080600060608486031215613ac757613ac6613749565b5b6000613ad586828701613996565b9350506020613ae686828701613996565b9250506040613af7868287016138e1565b9150509250925092565b60008060408385031215613b1857613b17613749565b5b6000613b26858286016138e1565b9250506020613b37858286016138e1565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613b6657613b65613b41565b5b8235905067ffffffffffffffff811115613b8357613b82613b46565b5b602083019150836001820283011115613b9f57613b9e613b4b565b5b9250929050565b60008060208385031215613bbd57613bbc613749565b5b600083013567ffffffffffffffff811115613bdb57613bda61374e565b5b613be785828601613b50565b92509250509250929050565b600060208284031215613c0957613c08613749565b5b6000613c1784828501613996565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613c5d82613854565b810181811067ffffffffffffffff82111715613c7c57613c7b613c25565b5b80604052505050565b6000613c8f61373f565b9050613c9b8282613c54565b919050565b600067ffffffffffffffff821115613cbb57613cba613c25565b5b613cc482613854565b9050602081019050919050565b82818337600083830152505050565b6000613cf3613cee84613ca0565b613c85565b905082815260208101848484011115613d0f57613d0e613c20565b5b613d1a848285613cd1565b509392505050565b600082601f830112613d3757613d36613b41565b5b8135613d47848260208601613ce0565b91505092915050565b60008060408385031215613d6757613d66613749565b5b600083013567ffffffffffffffff811115613d8557613d8461374e565b5b613d9185828601613d22565b9250506020613da2858286016138e1565b9150509250929050565b60008060408385031215613dc357613dc2613749565b5b6000613dd185828601613996565b9250506020613de285828601613a6c565b9150509250929050565b60008083601f840112613e0257613e01613b41565b5b8235905067ffffffffffffffff811115613e1f57613e1e613b46565b5b602083019150836020820283011115613e3b57613e3a613b4b565b5b9250929050565b60008083601f840112613e5857613e57613b41565b5b8235905067ffffffffffffffff811115613e7557613e74613b46565b5b602083019150836020820283011115613e9157613e90613b4b565b5b9250929050565b60008060008060408587031215613eb257613eb1613749565b5b600085013567ffffffffffffffff811115613ed057613ecf61374e565b5b613edc87828801613dec565b9450945050602085013567ffffffffffffffff811115613eff57613efe61374e565b5b613f0b87828801613e42565b925092505092959194509250565b600067ffffffffffffffff821115613f3457613f33613c25565b5b613f3d82613854565b9050602081019050919050565b6000613f5d613f5884613f19565b613c85565b905082815260208101848484011115613f7957613f78613c20565b5b613f84848285613cd1565b509392505050565b600082601f830112613fa157613fa0613b41565b5b8135613fb1848260208601613f4a565b91505092915050565b60008060008060808587031215613fd457613fd3613749565b5b6000613fe287828801613996565b9450506020613ff387828801613996565b9350506040614004878288016138e1565b925050606085013567ffffffffffffffff8111156140255761402461374e565b5b61403187828801613f8c565b91505092959194509250565b6000806040838503121561405457614053613749565b5b600061406285828601613996565b925050602061407385828601613996565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806140c457607f821691505b6020821081036140d7576140d661407d565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b6000614113601083613819565b915061411e826140dd565b602082019050919050565b6000602082019050818103600083015261414281614106565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b600061417f601283613819565b915061418a82614149565b602082019050919050565b600060208201905081810360008301526141ae81614172565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006141eb601383613819565b91506141f6826141b5565b602082019050919050565b6000602082019050818103600083015261421a816141de565b9050919050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b6000614257601483613819565b915061426282614221565b602082019050919050565b600060208201905081810360008301526142868161424a565b9050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b60006142c3601c83613819565b91506142ce8261428d565b602082019050919050565b600060208201905081810360008301526142f2816142b6565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b600061432f600c83613819565b915061433a826142f9565b602082019050919050565b6000602082019050818103600083015261435e81614322565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026143d27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614395565b6143dc8683614395565b95508019841693508086168417925050509392505050565b6000819050919050565b600061441961441461440f846138c0565b6143f4565b6138c0565b9050919050565b6000819050919050565b614433836143fe565b61444761443f82614420565b8484546143a2565b825550505050565b600090565b61445c61444f565b61446781848461442a565b505050565b5b8181101561448b57614480600082614454565b60018101905061446d565b5050565b601f8211156144d0576144a181614370565b6144aa84614385565b810160208510156144b9578190505b6144cd6144c585614385565b83018261446c565b50505b505050565b600082821c905092915050565b60006144f3600019846008026144d5565b1980831691505092915050565b600061450c83836144e2565b9150826002028217905092915050565b6145268383614365565b67ffffffffffffffff81111561453f5761453e613c25565b5b61454982546140ac565b61455482828561448f565b6000601f8311600181146145835760008415614571578287013590505b61457b8582614500565b8655506145e3565b601f19841661459186614370565b60005b828110156145b957848901358255600182019150602085019450602081019050614594565b868310156145d657848901356145d2601f8916826144e2565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b6000614622601483613819565b915061462d826145ec565b602082019050919050565b6000602082019050818103600083015261465181614615565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b600061468e600f83613819565b915061469982614658565b602082019050919050565b600060208201905081810360008301526146bd81614681565b9050919050565b60006080820190506146d960008301876139eb565b6146e66020830186613955565b6146f360408301856139eb565b61470060608301846139eb565b95945050505050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b6000614765603783613819565b915061477082614709565b604082019050919050565b6000602082019050818103600083015261479481614758565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006147f7602e83613819565b91506148028261479b565b604082019050919050565b60006020820190508181036000830152614826816147ea565b9050919050565b6148368261380e565b67ffffffffffffffff81111561484f5761484e613c25565b5b61485982546140ac565b61486482828561448f565b600060209050601f8311600181146148975760008415614885578287015190505b61488f8582614500565b8655506148f7565b601f1984166148a586614370565b60005b828110156148cd578489015182556001820191506020850194506020810190506148a8565b868310156148ea57848901516148e6601f8916826144e2565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b600061493161492c614927846148ff565b6143f4565b614909565b9050919050565b61494181614916565b82525050565b600060208201905061495c6000830184614938565b92915050565b600060608201905061497760008301866139eb565b6149846020830185613955565b61499160408301846139eb565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b60006149cf600783613819565b91506149da82614999565b602082019050919050565b600060208201905081810360008301526149fe816149c2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614a6e826138c0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614aa057614a9f614a34565b5b600182019050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614ae1600f83613819565b9150614aec82614aab565b602082019050919050565b60006020820190508181036000830152614b1081614ad4565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614b73602683613819565b9150614b7e82614b17565b604082019050919050565b60006020820190508181036000830152614ba281614b66565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614bdf602083613819565b9150614bea82614ba9565b602082019050919050565b60006020820190508181036000830152614c0e81614bd2565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b6000614c4b600f83613819565b9150614c5682614c15565b602082019050919050565b60006020820190508181036000830152614c7a81614c3e565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b6000614cb7601183613819565b9150614cc282614c81565b602082019050919050565b60006020820190508181036000830152614ce681614caa565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b6000614d23601b83613819565b9150614d2e82614ced565b602082019050919050565b60006020820190508181036000830152614d5281614d16565b9050919050565b6000614d64826138c0565b9150614d6f836138c0565b9250828201905080821115614d8757614d86614a34565b5b92915050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b6000614dc3601783613819565b9150614dce82614d8d565b602082019050919050565b60006020820190508181036000830152614df281614db6565b9050919050565b6000614e04826138c0565b915060008203614e1757614e16614a34565b5b600182039050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000614e7e602b83613819565b9150614e8982614e22565b604082019050919050565b60006020820190508181036000830152614ead81614e71565b9050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b6000614eea600d83613819565b9150614ef582614eb4565b602082019050919050565b60006020820190508181036000830152614f1981614edd565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000614f7c603483613819565b9150614f8782614f20565b604082019050919050565b60006020820190508181036000830152614fab81614f6f565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614fd982614fb2565b614fe38185614fbd565b9350614ff381856020860161382a565b614ffc81613854565b840191505092915050565b600060808201905061501c6000830187613955565b6150296020830186613955565b61503660408301856139eb565b81810360608301526150488184614fce565b905095945050505050565b6000815190506150628161377f565b92915050565b60006020828403121561507e5761507d613749565b5b600061508c84828501615053565b9150509291505056fea26469706673582212209721d7bfbcd8e5cd62de2691f6a2a8a01fe7c45a27a69ed2ddb20ff7c16b783364736f6c63430008120033
Deployed Bytecode Sourcemap
135092:4025: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;:::-;;136166:310;;;:::i;:::-;;45831:371;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137369:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138328:367;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86777:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22783:71;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86919:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63801:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135301:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135197:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137480:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137092:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137940:380;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51787:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22723:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135231:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135138:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47111:257;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21384:103;;;;;;;;;;;;;:::i;:::-;;23303:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135693:338;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20743:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87065:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50546:128;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57520:258;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137609:323;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23425;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22659:57;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;138703:411;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;136873:211;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135166:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136039:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57935:188;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135268:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21642:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137267:94;;;;;;;;;;;;;;;;;;;;;;;:::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;136166:310::-;136216:10;;;;;;;;;;;136208:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;136279:9;;136266;:22;;136258:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;136353:12;;136330:8;:20;136339:10;136330:20;;;;;;;;;;;;;;;;:35;136322:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;136433:1;136410:8;:20;136419:10;136410:20;;;;;;;;;;;;;;;:24;;;;136445:23;136454:10;136466:1;136445:8;:23::i;:::-;136166:310::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;137369:103::-;20629:13;:11;:13::i;:::-;137453:11:::1;137440:10;;:24;;;;;;;;;;;;;;;;;;137369:103:::0;:::o;138328:367::-;138479:14;;;;;;;;;;;138471:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;138582:1;138551:18;:27;138570:7;138551:27;;;;;;;;;;;;:32;138529:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;138650:37;138669:4;138675:2;138679:7;138650:18;:37::i;:::-;138328: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;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;135301:22::-;;;;;;;;;;;;;:::o;135197:27::-;;;;:::o;137480:119::-;20629:13;:11;:13::i;:::-;137576:15:::1;137559:14;;:32;;;;;;;;;;;;;;;;;;137480:119:::0;:::o;137092:94::-;20629:13;:11;:13::i;:::-;137174:4:::1;;137164:7;:14;;;;;;;:::i;:::-;;137092:94:::0;;:::o;137940:380::-;138016:16;138024:7;138016;:16::i;:::-;138002:30;;:10;:30;;;137994:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;138107:1;138076:18;:27;138095:7;138076:27;;;;;;;;;;;;:32;138068:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;138141:22;138166:18;:27;138185:7;138166:27;;;;;;;;;;;;138141:52;;138234:1;138204:18;:27;138223:7;138204:27;;;;;;;;;;;:31;;;;138251:61;138259:7;138268:10;138280:14;138296:15;138251:61;;;;;;;;;:::i;:::-;;;;;;;;137983:337;137940:380;:::o;51787:152::-;51859:7;51902:27;51921:7;51902:18;:27::i;:::-;51879:52;;51787:152;;;:::o;22723:53::-;;;;;;;;;;;;;;;;;:::o;135231:24::-;;;;:::o;135138:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::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;135693:338::-;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;135827:47:::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;::::0;:14:::2;:47::i;:::-;135897:4;135887:7;:14;;;;;;:::i;:::-;;135929:5;135912:14;;:22;;;;;;;;;;;;;;;;;;135958:5;135945:10;;:18;;;;;;;;;;;;;;;;;;135989:1;135974:12;:16;;;;136013:10;136001:9;:22;;;;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;135693:338;;:::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;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;137609:323::-;137683:16;137691:7;137683;:16::i;:::-;137669:30;;:10;:30;;;137661:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;137774:1;137743:18;:27;137762:7;137743:27;;;;;;;;;;;;:32;137735:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;137838:15;137808:18;:27;137827:7;137808:27;;;;;;;;;;;:45;;;;137869:55;137875:7;137884:10;137896:18;:27;137915:7;137896:27;;;;;;;;;;;;137869:55;;;;;;;;:::i;:::-;;;;;;;;137609: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;138703:411::-;138887:14;;;;;;;;;;;138879:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;138990:1;138959:18;:27;138978:7;138959:27;;;;;;;;;;;;:32;138937:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;139058:48;139081:4;139087:2;139091:7;139100:5;139058:22;:48::i;:::-;138703:411;;;;:::o;136873:211::-;136975:13;137014:17;137022:8;137014:7;:17::i;:::-;137006:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;137069:7;137062:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136873:211;;;:::o;135166:24::-;;;;:::o;136039:119::-;20629:13;:11;:13::i;:::-;136122:28:::1;136131:8;136141;136122;:28::i;:::-;136039: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;135268:26::-;;;;;;;;;;;;;:::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;137267:94::-;20629:13;:11;:13::i;:::-;137347:6:::1;137335:9;:18;;;;137267:94:::0;:::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;136484:107::-;136558:25;136564:8;136574;136558:5;:25::i;:::-;136484:107;;:::o;136648:101::-;136713:7;136740:1;136733:8;;136648: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;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;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;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;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;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;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;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;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;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:117::-;9338:1;9335;9328:12;9352:180;9400:77;9397:1;9390:88;9497:4;9494:1;9487:15;9521:4;9518:1;9511:15;9538:281;9621:27;9643:4;9621:27;:::i;:::-;9613:6;9609:40;9751:6;9739:10;9736:22;9715:18;9703:10;9700:34;9697:62;9694:88;;;9762:18;;:::i;:::-;9694:88;9802:10;9798:2;9791:22;9581:238;9538:281;;:::o;9825:129::-;9859:6;9886:20;;:::i;:::-;9876:30;;9915:33;9943:4;9935:6;9915:33;:::i;:::-;9825:129;;;:::o;9960:308::-;10022:4;10112:18;10104:6;10101:30;10098:56;;;10134:18;;:::i;:::-;10098:56;10172:29;10194:6;10172:29;:::i;:::-;10164:37;;10256:4;10250;10246:15;10238:23;;9960:308;;;:::o;10274:146::-;10371:6;10366:3;10361;10348:30;10412:1;10403:6;10398:3;10394:16;10387:27;10274:146;;;:::o;10426:425::-;10504:5;10529:66;10545:49;10587:6;10545:49;:::i;:::-;10529:66;:::i;:::-;10520:75;;10618:6;10611:5;10604:21;10656:4;10649:5;10645:16;10694:3;10685:6;10680:3;10676:16;10673:25;10670:112;;;10701:79;;:::i;:::-;10670:112;10791:54;10838:6;10833:3;10828;10791:54;:::i;:::-;10510:341;10426:425;;;;;:::o;10871:340::-;10927:5;10976:3;10969:4;10961:6;10957:17;10953:27;10943:122;;10984:79;;:::i;:::-;10943:122;11101:6;11088:20;11126:79;11201:3;11193:6;11186:4;11178:6;11174:17;11126:79;:::i;:::-;11117:88;;10933:278;10871:340;;;;:::o;11217:654::-;11295:6;11303;11352:2;11340:9;11331:7;11327:23;11323:32;11320:119;;;11358:79;;:::i;:::-;11320:119;11506:1;11495:9;11491:17;11478:31;11536:18;11528:6;11525:30;11522:117;;;11558:79;;:::i;:::-;11522:117;11663:63;11718:7;11709:6;11698:9;11694:22;11663:63;:::i;:::-;11653:73;;11449:287;11775:2;11801:53;11846:7;11837:6;11826:9;11822:22;11801:53;:::i;:::-;11791:63;;11746:118;11217:654;;;;;:::o;11877:468::-;11942:6;11950;11999:2;11987:9;11978:7;11974:23;11970:32;11967:119;;;12005:79;;:::i;:::-;11967:119;12125:1;12150:53;12195:7;12186:6;12175:9;12171:22;12150:53;:::i;:::-;12140:63;;12096:117;12252:2;12278:50;12320:7;12311:6;12300:9;12296:22;12278:50;:::i;:::-;12268:60;;12223:115;11877:468;;;;;:::o;12368:568::-;12441:8;12451:6;12501:3;12494:4;12486:6;12482:17;12478:27;12468:122;;12509:79;;:::i;:::-;12468:122;12622:6;12609:20;12599:30;;12652:18;12644:6;12641:30;12638:117;;;12674:79;;:::i;:::-;12638:117;12788:4;12780:6;12776:17;12764:29;;12842:3;12834:4;12826:6;12822:17;12812:8;12808:32;12805:41;12802:128;;;12849:79;;:::i;:::-;12802:128;12368:568;;;;;:::o;12956:565::-;13026:8;13036:6;13086:3;13079:4;13071:6;13067:17;13063:27;13053:122;;13094:79;;:::i;:::-;13053:122;13207:6;13194:20;13184:30;;13237:18;13229:6;13226:30;13223:117;;;13259:79;;:::i;:::-;13223:117;13373:4;13365:6;13361:17;13349:29;;13427:3;13419:4;13411:6;13407:17;13397:8;13393:32;13390:41;13387:128;;;13434:79;;:::i;:::-;13387:128;12956:565;;;;;:::o;13527:928::-;13646:6;13654;13662;13670;13719:2;13707:9;13698:7;13694:23;13690:32;13687:119;;;13725:79;;:::i;:::-;13687:119;13873:1;13862:9;13858:17;13845:31;13903:18;13895:6;13892:30;13889:117;;;13925:79;;:::i;:::-;13889:117;14038:80;14110:7;14101:6;14090:9;14086:22;14038:80;:::i;:::-;14020:98;;;;13816:312;14195:2;14184:9;14180:18;14167:32;14226:18;14218:6;14215:30;14212:117;;;14248:79;;:::i;:::-;14212:117;14361:77;14430:7;14421:6;14410:9;14406:22;14361:77;:::i;:::-;14343:95;;;;14138:310;13527:928;;;;;;;:::o;14461:307::-;14522:4;14612:18;14604:6;14601:30;14598:56;;;14634:18;;:::i;:::-;14598:56;14672:29;14694:6;14672:29;:::i;:::-;14664:37;;14756:4;14750;14746:15;14738:23;;14461:307;;;:::o;14774:423::-;14851:5;14876:65;14892:48;14933:6;14892:48;:::i;:::-;14876:65;:::i;:::-;14867:74;;14964:6;14957:5;14950:21;15002:4;14995:5;14991:16;15040:3;15031:6;15026:3;15022:16;15019:25;15016:112;;;15047:79;;:::i;:::-;15016:112;15137:54;15184:6;15179:3;15174;15137:54;:::i;:::-;14857:340;14774:423;;;;;:::o;15216:338::-;15271:5;15320:3;15313:4;15305:6;15301:17;15297:27;15287:122;;15328:79;;:::i;:::-;15287:122;15445:6;15432:20;15470:78;15544:3;15536:6;15529:4;15521:6;15517:17;15470:78;:::i;:::-;15461:87;;15277:277;15216:338;;;;:::o;15560:943::-;15655:6;15663;15671;15679;15728:3;15716:9;15707:7;15703:23;15699:33;15696:120;;;15735:79;;:::i;:::-;15696:120;15855:1;15880:53;15925:7;15916:6;15905:9;15901:22;15880:53;:::i;:::-;15870:63;;15826:117;15982:2;16008:53;16053:7;16044:6;16033:9;16029:22;16008:53;:::i;:::-;15998:63;;15953:118;16110:2;16136:53;16181:7;16172:6;16161:9;16157:22;16136:53;:::i;:::-;16126:63;;16081:118;16266:2;16255:9;16251:18;16238:32;16297:18;16289:6;16286:30;16283:117;;;16319:79;;:::i;:::-;16283:117;16424:62;16478:7;16469:6;16458:9;16454:22;16424:62;:::i;:::-;16414:72;;16209:287;15560:943;;;;;;;:::o;16509:474::-;16577:6;16585;16634:2;16622:9;16613:7;16609:23;16605:32;16602:119;;;16640:79;;:::i;:::-;16602:119;16760:1;16785:53;16830:7;16821:6;16810:9;16806:22;16785:53;:::i;:::-;16775:63;;16731:117;16887:2;16913:53;16958:7;16949:6;16938:9;16934:22;16913:53;:::i;:::-;16903:63;;16858:118;16509:474;;;;;:::o;16989:180::-;17037:77;17034:1;17027:88;17134:4;17131:1;17124:15;17158:4;17155:1;17148:15;17175:320;17219:6;17256:1;17250:4;17246:12;17236:22;;17303:1;17297:4;17293:12;17324:18;17314:81;;17380:4;17372:6;17368:17;17358:27;;17314:81;17442:2;17434:6;17431:14;17411:18;17408:38;17405:84;;17461:18;;:::i;:::-;17405:84;17226:269;17175:320;;;:::o;17501:166::-;17641:18;17637:1;17629:6;17625:14;17618:42;17501:166;:::o;17673:366::-;17815:3;17836:67;17900:2;17895:3;17836:67;:::i;:::-;17829:74;;17912:93;18001:3;17912:93;:::i;:::-;18030:2;18025:3;18021:12;18014:19;;17673:366;;;:::o;18045:419::-;18211:4;18249:2;18238:9;18234:18;18226:26;;18298:9;18292:4;18288:20;18284:1;18273:9;18269:17;18262:47;18326:131;18452:4;18326:131;:::i;:::-;18318:139;;18045:419;;;:::o;18470:168::-;18610:20;18606:1;18598:6;18594:14;18587:44;18470:168;:::o;18644:366::-;18786:3;18807:67;18871:2;18866:3;18807:67;:::i;:::-;18800:74;;18883:93;18972:3;18883:93;:::i;:::-;19001:2;18996:3;18992:12;18985:19;;18644:366;;;:::o;19016:419::-;19182:4;19220:2;19209:9;19205:18;19197:26;;19269:9;19263:4;19259:20;19255:1;19244:9;19240:17;19233:47;19297:131;19423:4;19297:131;:::i;:::-;19289:139;;19016:419;;;:::o;19441:169::-;19581:21;19577:1;19569:6;19565:14;19558:45;19441:169;:::o;19616:366::-;19758:3;19779:67;19843:2;19838:3;19779:67;:::i;:::-;19772:74;;19855:93;19944:3;19855:93;:::i;:::-;19973:2;19968:3;19964:12;19957:19;;19616:366;;;:::o;19988:419::-;20154:4;20192:2;20181:9;20177:18;20169:26;;20241:9;20235:4;20231:20;20227:1;20216:9;20212:17;20205:47;20269:131;20395:4;20269:131;:::i;:::-;20261:139;;19988:419;;;:::o;20413:170::-;20553:22;20549:1;20541:6;20537:14;20530:46;20413:170;:::o;20589:366::-;20731:3;20752:67;20816:2;20811:3;20752:67;:::i;:::-;20745:74;;20828:93;20917:3;20828:93;:::i;:::-;20946:2;20941:3;20937:12;20930:19;;20589:366;;;:::o;20961:419::-;21127:4;21165:2;21154:9;21150:18;21142:26;;21214:9;21208:4;21204:20;21200:1;21189:9;21185:17;21178:47;21242:131;21368:4;21242:131;:::i;:::-;21234:139;;20961:419;;;:::o;21386:178::-;21526:30;21522:1;21514:6;21510:14;21503:54;21386:178;:::o;21570:366::-;21712:3;21733:67;21797:2;21792:3;21733:67;:::i;:::-;21726:74;;21809:93;21898:3;21809:93;:::i;:::-;21927:2;21922:3;21918:12;21911:19;;21570:366;;;:::o;21942:419::-;22108:4;22146:2;22135:9;22131:18;22123:26;;22195:9;22189:4;22185:20;22181:1;22170:9;22166:17;22159:47;22223:131;22349:4;22223:131;:::i;:::-;22215:139;;21942:419;;;:::o;22367:162::-;22507:14;22503:1;22495:6;22491:14;22484:38;22367:162;:::o;22535:366::-;22677:3;22698:67;22762:2;22757:3;22698:67;:::i;:::-;22691:74;;22774:93;22863:3;22774:93;:::i;:::-;22892:2;22887:3;22883:12;22876:19;;22535:366;;;:::o;22907:419::-;23073:4;23111:2;23100:9;23096:18;23088:26;;23160:9;23154:4;23150:20;23146:1;23135:9;23131:17;23124:47;23188:131;23314:4;23188:131;:::i;:::-;23180:139;;22907:419;;;:::o;23332:97::-;23391:6;23419:3;23409:13;;23332:97;;;;:::o;23435:141::-;23484:4;23507:3;23499:11;;23530:3;23527:1;23520:14;23564:4;23561:1;23551:18;23543:26;;23435:141;;;:::o;23582:93::-;23619:6;23666:2;23661;23654:5;23650:14;23646:23;23636:33;;23582:93;;;:::o;23681:107::-;23725:8;23775:5;23769:4;23765:16;23744:37;;23681:107;;;;:::o;23794:393::-;23863:6;23913:1;23901:10;23897:18;23936:97;23966:66;23955:9;23936:97;:::i;:::-;24054:39;24084:8;24073:9;24054:39;:::i;:::-;24042:51;;24126:4;24122:9;24115:5;24111:21;24102:30;;24175:4;24165:8;24161:19;24154:5;24151:30;24141:40;;23870:317;;23794:393;;;;;:::o;24193:60::-;24221:3;24242:5;24235:12;;24193:60;;;:::o;24259:142::-;24309:9;24342:53;24360:34;24369:24;24387:5;24369:24;:::i;:::-;24360:34;:::i;:::-;24342:53;:::i;:::-;24329:66;;24259:142;;;:::o;24407:75::-;24450:3;24471:5;24464:12;;24407:75;;;:::o;24488:269::-;24598:39;24629:7;24598:39;:::i;:::-;24659:91;24708:41;24732:16;24708:41;:::i;:::-;24700:6;24693:4;24687:11;24659:91;:::i;:::-;24653:4;24646:105;24564:193;24488:269;;;:::o;24763:73::-;24808:3;24763:73;:::o;24842:189::-;24919:32;;:::i;:::-;24960:65;25018:6;25010;25004:4;24960:65;:::i;:::-;24895:136;24842:189;;:::o;25037:186::-;25097:120;25114:3;25107:5;25104:14;25097:120;;;25168:39;25205:1;25198:5;25168:39;:::i;:::-;25141:1;25134:5;25130:13;25121:22;;25097:120;;;25037:186;;:::o;25229:543::-;25330:2;25325:3;25322:11;25319:446;;;25364:38;25396:5;25364:38;:::i;:::-;25448:29;25466:10;25448:29;:::i;:::-;25438:8;25434:44;25631:2;25619:10;25616:18;25613:49;;;25652:8;25637:23;;25613:49;25675:80;25731:22;25749:3;25731:22;:::i;:::-;25721:8;25717:37;25704:11;25675:80;:::i;:::-;25334:431;;25319:446;25229:543;;;:::o;25778:117::-;25832:8;25882:5;25876:4;25872:16;25851:37;;25778:117;;;;:::o;25901:169::-;25945:6;25978:51;26026:1;26022:6;26014:5;26011:1;26007:13;25978:51;:::i;:::-;25974:56;26059:4;26053;26049:15;26039:25;;25952:118;25901:169;;;;:::o;26075:295::-;26151:4;26297:29;26322:3;26316:4;26297:29;:::i;:::-;26289:37;;26359:3;26356:1;26352:11;26346:4;26343:21;26335:29;;26075:295;;;;:::o;26375:1403::-;26499:44;26539:3;26534;26499:44;:::i;:::-;26608:18;26600:6;26597:30;26594:56;;;26630:18;;:::i;:::-;26594:56;26674:38;26706:4;26700:11;26674:38;:::i;:::-;26759:67;26819:6;26811;26805:4;26759:67;:::i;:::-;26853:1;26882:2;26874:6;26871:14;26899:1;26894:632;;;;27570:1;27587:6;27584:84;;;27643:9;27638:3;27634:19;27621:33;27612:42;;27584:84;27694:67;27754:6;27747:5;27694:67;:::i;:::-;27688:4;27681:81;27543:229;26864:908;;26894:632;26946:4;26942:9;26934:6;26930:22;26980:37;27012:4;26980:37;:::i;:::-;27039:1;27053:215;27067:7;27064:1;27061:14;27053:215;;;27153:9;27148:3;27144:19;27131:33;27123:6;27116:49;27204:1;27196:6;27192:14;27182:24;;27251:2;27240:9;27236:18;27223:31;;27090:4;27087:1;27083:12;27078:17;;27053:215;;;27296:6;27287:7;27284:19;27281:186;;;27361:9;27356:3;27352:19;27339:33;27404:48;27446:4;27438:6;27434:17;27423:9;27404:48;:::i;:::-;27396:6;27389:64;27304:163;27281:186;27513:1;27509;27501:6;27497:14;27493:22;27487:4;27480:36;26901:625;;;26864:908;;26474:1304;;;26375:1403;;;:::o;27784:170::-;27924:22;27920:1;27912:6;27908:14;27901:46;27784:170;:::o;27960:366::-;28102:3;28123:67;28187:2;28182:3;28123:67;:::i;:::-;28116:74;;28199:93;28288:3;28199:93;:::i;:::-;28317:2;28312:3;28308:12;28301:19;;27960:366;;;:::o;28332:419::-;28498:4;28536:2;28525:9;28521:18;28513:26;;28585:9;28579:4;28575:20;28571:1;28560:9;28556:17;28549:47;28613:131;28739:4;28613:131;:::i;:::-;28605:139;;28332:419;;;:::o;28757:165::-;28897:17;28893:1;28885:6;28881:14;28874:41;28757:165;:::o;28928:366::-;29070:3;29091:67;29155:2;29150:3;29091:67;:::i;:::-;29084:74;;29167:93;29256:3;29167:93;:::i;:::-;29285:2;29280:3;29276:12;29269:19;;28928:366;;;:::o;29300:419::-;29466:4;29504:2;29493:9;29489:18;29481:26;;29553:9;29547:4;29543:20;29539:1;29528:9;29524:17;29517:47;29581:131;29707:4;29581:131;:::i;:::-;29573:139;;29300:419;;;:::o;29725:553::-;29902:4;29940:3;29929:9;29925:19;29917:27;;29954:71;30022:1;30011:9;30007:17;29998:6;29954:71;:::i;:::-;30035:72;30103:2;30092:9;30088:18;30079:6;30035:72;:::i;:::-;30117;30185:2;30174:9;30170:18;30161:6;30117:72;:::i;:::-;30199;30267:2;30256:9;30252:18;30243:6;30199:72;:::i;:::-;29725:553;;;;;;;:::o;30284:242::-;30424:34;30420:1;30412:6;30408:14;30401:58;30493:25;30488:2;30480:6;30476:15;30469:50;30284:242;:::o;30532:366::-;30674:3;30695:67;30759:2;30754:3;30695:67;:::i;:::-;30688:74;;30771:93;30860:3;30771:93;:::i;:::-;30889:2;30884:3;30880:12;30873:19;;30532:366;;;:::o;30904:419::-;31070:4;31108:2;31097:9;31093:18;31085:26;;31157:9;31151:4;31147:20;31143:1;31132:9;31128:17;31121:47;31185:131;31311:4;31185:131;:::i;:::-;31177:139;;30904:419;;;:::o;31329:233::-;31469:34;31465:1;31457:6;31453:14;31446:58;31538:16;31533:2;31525:6;31521:15;31514:41;31329:233;:::o;31568:366::-;31710:3;31731:67;31795:2;31790:3;31731:67;:::i;:::-;31724:74;;31807:93;31896:3;31807:93;:::i;:::-;31925:2;31920:3;31916:12;31909:19;;31568:366;;;:::o;31940:419::-;32106:4;32144:2;32133:9;32129:18;32121:26;;32193:9;32187:4;32183:20;32179:1;32168:9;32164:17;32157:47;32221:131;32347:4;32221:131;:::i;:::-;32213:139;;31940:419;;;:::o;32365:1395::-;32482:37;32515:3;32482:37;:::i;:::-;32584:18;32576:6;32573:30;32570:56;;;32606:18;;:::i;:::-;32570:56;32650:38;32682:4;32676:11;32650:38;:::i;:::-;32735:67;32795:6;32787;32781:4;32735:67;:::i;:::-;32829:1;32853:4;32840:17;;32885:2;32877:6;32874:14;32902:1;32897:618;;;;33559:1;33576:6;33573:77;;;33625:9;33620:3;33616:19;33610:26;33601:35;;33573:77;33676:67;33736:6;33729:5;33676:67;:::i;:::-;33670:4;33663:81;33532:222;32867:887;;32897:618;32949:4;32945:9;32937:6;32933:22;32983:37;33015:4;32983:37;:::i;:::-;33042:1;33056:208;33070:7;33067:1;33064:14;33056:208;;;33149:9;33144:3;33140:19;33134:26;33126:6;33119:42;33200:1;33192:6;33188:14;33178:24;;33247:2;33236:9;33232:18;33219:31;;33093:4;33090:1;33086:12;33081:17;;33056:208;;;33292:6;33283:7;33280:19;33277:179;;;33350:9;33345:3;33341:19;33335:26;33393:48;33435:4;33427:6;33423:17;33412:9;33393:48;:::i;:::-;33385:6;33378:64;33300:156;33277:179;33502:1;33498;33490:6;33486:14;33482:22;33476:4;33469:36;32904:611;;;32867:887;;32457:1303;;;32365:1395;;:::o;33766:85::-;33811:7;33840:5;33829:16;;33766:85;;;:::o;33857:86::-;33892:7;33932:4;33925:5;33921:16;33910:27;;33857:86;;;:::o;33949:154::-;34005:9;34038:59;34054:42;34063:32;34089:5;34063:32;:::i;:::-;34054:42;:::i;:::-;34038:59;:::i;:::-;34025:72;;33949:154;;;:::o;34109:143::-;34202:43;34239:5;34202:43;:::i;:::-;34197:3;34190:56;34109:143;;:::o;34258:234::-;34357:4;34395:2;34384:9;34380:18;34372:26;;34408:77;34482:1;34471:9;34467:17;34458:6;34408:77;:::i;:::-;34258:234;;;;:::o;34498:442::-;34647:4;34685:2;34674:9;34670:18;34662:26;;34698:71;34766:1;34755:9;34751:17;34742:6;34698:71;:::i;:::-;34779:72;34847:2;34836:9;34832:18;34823:6;34779:72;:::i;:::-;34861;34929:2;34918:9;34914:18;34905:6;34861:72;:::i;:::-;34498:442;;;;;;:::o;34946:157::-;35086:9;35082:1;35074:6;35070:14;35063:33;34946:157;:::o;35109:365::-;35251:3;35272:66;35336:1;35331:3;35272:66;:::i;:::-;35265:73;;35347:93;35436:3;35347:93;:::i;:::-;35465:2;35460:3;35456:12;35449:19;;35109:365;;;:::o;35480:419::-;35646:4;35684:2;35673:9;35669:18;35661:26;;35733:9;35727:4;35723:20;35719:1;35708:9;35704:17;35697:47;35761:131;35887:4;35761:131;:::i;:::-;35753:139;;35480:419;;;:::o;35905:180::-;35953:77;35950:1;35943:88;36050:4;36047:1;36040:15;36074:4;36071:1;36064:15;36091:180;36139:77;36136:1;36129:88;36236:4;36233:1;36226:15;36260:4;36257:1;36250:15;36277:233;36316:3;36339:24;36357:5;36339:24;:::i;:::-;36330:33;;36385:66;36378:5;36375:77;36372:103;;36455:18;;:::i;:::-;36372:103;36502:1;36495:5;36491:13;36484:20;;36277:233;;;:::o;36516:165::-;36656:17;36652:1;36644:6;36640:14;36633:41;36516:165;:::o;36687:366::-;36829:3;36850:67;36914:2;36909:3;36850:67;:::i;:::-;36843:74;;36926:93;37015:3;36926:93;:::i;:::-;37044:2;37039:3;37035:12;37028:19;;36687:366;;;:::o;37059:419::-;37225:4;37263:2;37252:9;37248:18;37240:26;;37312:9;37306:4;37302:20;37298:1;37287:9;37283:17;37276:47;37340:131;37466:4;37340:131;:::i;:::-;37332:139;;37059:419;;;:::o;37484:225::-;37624:34;37620:1;37612:6;37608:14;37601:58;37693:8;37688:2;37680:6;37676:15;37669:33;37484:225;:::o;37715:366::-;37857:3;37878:67;37942:2;37937:3;37878:67;:::i;:::-;37871:74;;37954:93;38043:3;37954:93;:::i;:::-;38072:2;38067:3;38063:12;38056:19;;37715:366;;;:::o;38087:419::-;38253:4;38291:2;38280:9;38276:18;38268:26;;38340:9;38334:4;38330:20;38326:1;38315:9;38311:17;38304:47;38368:131;38494:4;38368:131;:::i;:::-;38360:139;;38087:419;;;:::o;38512:182::-;38652:34;38648:1;38640:6;38636:14;38629:58;38512:182;:::o;38700:366::-;38842:3;38863:67;38927:2;38922:3;38863:67;:::i;:::-;38856:74;;38939:93;39028:3;38939:93;:::i;:::-;39057:2;39052:3;39048:12;39041:19;;38700:366;;;:::o;39072:419::-;39238:4;39276:2;39265:9;39261:18;39253:26;;39325:9;39319:4;39315:20;39311:1;39300:9;39296:17;39289:47;39353:131;39479:4;39353:131;:::i;:::-;39345:139;;39072:419;;;:::o;39497:165::-;39637:17;39633:1;39625:6;39621:14;39614:41;39497:165;:::o;39668:366::-;39810:3;39831:67;39895:2;39890:3;39831:67;:::i;:::-;39824:74;;39907:93;39996:3;39907:93;:::i;:::-;40025:2;40020:3;40016:12;40009:19;;39668:366;;;:::o;40040:419::-;40206:4;40244:2;40233:9;40229:18;40221:26;;40293:9;40287:4;40283:20;40279:1;40268:9;40264:17;40257:47;40321:131;40447:4;40321:131;:::i;:::-;40313:139;;40040:419;;;:::o;40465:167::-;40605:19;40601:1;40593:6;40589:14;40582:43;40465:167;:::o;40638:366::-;40780:3;40801:67;40865:2;40860:3;40801:67;:::i;:::-;40794:74;;40877:93;40966:3;40877:93;:::i;:::-;40995:2;40990:3;40986:12;40979:19;;40638:366;;;:::o;41010:419::-;41176:4;41214:2;41203:9;41199:18;41191:26;;41263:9;41257:4;41253:20;41249:1;41238:9;41234:17;41227:47;41291:131;41417:4;41291:131;:::i;:::-;41283:139;;41010:419;;;:::o;41435:177::-;41575:29;41571:1;41563:6;41559:14;41552:53;41435:177;:::o;41618:366::-;41760:3;41781:67;41845:2;41840:3;41781:67;:::i;:::-;41774:74;;41857:93;41946:3;41857:93;:::i;:::-;41975:2;41970:3;41966:12;41959:19;;41618:366;;;:::o;41990:419::-;42156:4;42194:2;42183:9;42179:18;42171:26;;42243:9;42237:4;42233:20;42229:1;42218:9;42214:17;42207:47;42271:131;42397:4;42271:131;:::i;:::-;42263:139;;41990:419;;;:::o;42415:191::-;42455:3;42474:20;42492:1;42474:20;:::i;:::-;42469:25;;42508:20;42526:1;42508:20;:::i;:::-;42503:25;;42551:1;42548;42544:9;42537:16;;42572:3;42569:1;42566:10;42563:36;;;42579:18;;:::i;:::-;42563:36;42415:191;;;;:::o;42612:173::-;42752:25;42748:1;42740:6;42736:14;42729:49;42612:173;:::o;42791:366::-;42933:3;42954:67;43018:2;43013:3;42954:67;:::i;:::-;42947:74;;43030:93;43119:3;43030:93;:::i;:::-;43148:2;43143:3;43139:12;43132:19;;42791:366;;;:::o;43163:419::-;43329:4;43367:2;43356:9;43352:18;43344:26;;43416:9;43410:4;43406:20;43402:1;43391:9;43387:17;43380:47;43444:131;43570:4;43444:131;:::i;:::-;43436:139;;43163:419;;;:::o;43588:171::-;43627:3;43650:24;43668:5;43650:24;:::i;:::-;43641:33;;43696:4;43689:5;43686:15;43683:41;;43704:18;;:::i;:::-;43683:41;43751:1;43744:5;43740:13;43733:20;;43588:171;;;:::o;43765:230::-;43905:34;43901:1;43893:6;43889:14;43882:58;43974:13;43969:2;43961:6;43957:15;43950:38;43765:230;:::o;44001:366::-;44143:3;44164:67;44228:2;44223:3;44164:67;:::i;:::-;44157:74;;44240:93;44329:3;44240:93;:::i;:::-;44358:2;44353:3;44349:12;44342:19;;44001:366;;;:::o;44373:419::-;44539:4;44577:2;44566:9;44562:18;44554:26;;44626:9;44620:4;44616:20;44612:1;44601:9;44597:17;44590:47;44654:131;44780:4;44654:131;:::i;:::-;44646:139;;44373:419;;;:::o;44798:163::-;44938:15;44934:1;44926:6;44922:14;44915:39;44798:163;:::o;44967:366::-;45109:3;45130:67;45194:2;45189:3;45130:67;:::i;:::-;45123:74;;45206:93;45295:3;45206:93;:::i;:::-;45324:2;45319:3;45315:12;45308:19;;44967:366;;;:::o;45339:419::-;45505:4;45543:2;45532:9;45528:18;45520:26;;45592:9;45586:4;45582:20;45578:1;45567:9;45563:17;45556:47;45620:131;45746:4;45620:131;:::i;:::-;45612:139;;45339:419;;;:::o;45764:239::-;45904:34;45900:1;45892:6;45888:14;45881:58;45973:22;45968:2;45960:6;45956:15;45949:47;45764:239;:::o;46009:366::-;46151:3;46172:67;46236:2;46231:3;46172:67;:::i;:::-;46165:74;;46248:93;46337:3;46248:93;:::i;:::-;46366:2;46361:3;46357:12;46350:19;;46009:366;;;:::o;46381:419::-;46547:4;46585:2;46574:9;46570:18;46562:26;;46634:9;46628:4;46624:20;46620:1;46609:9;46605:17;46598:47;46662:131;46788:4;46662:131;:::i;:::-;46654:139;;46381:419;;;:::o;46806:98::-;46857:6;46891:5;46885:12;46875:22;;46806:98;;;:::o;46910:168::-;46993:11;47027:6;47022:3;47015:19;47067:4;47062:3;47058:14;47043:29;;46910:168;;;;:::o;47084:373::-;47170:3;47198:38;47230:5;47198:38;:::i;:::-;47252:70;47315:6;47310:3;47252:70;:::i;:::-;47245:77;;47331:65;47389:6;47384:3;47377:4;47370:5;47366:16;47331:65;:::i;:::-;47421:29;47443:6;47421:29;:::i;:::-;47416:3;47412:39;47405:46;;47174:283;47084:373;;;;:::o;47463:640::-;47658:4;47696:3;47685:9;47681:19;47673:27;;47710:71;47778:1;47767:9;47763:17;47754:6;47710:71;:::i;:::-;47791:72;47859:2;47848:9;47844:18;47835:6;47791:72;:::i;:::-;47873;47941:2;47930:9;47926:18;47917:6;47873:72;:::i;:::-;47992:9;47986:4;47982:20;47977:2;47966:9;47962:18;47955:48;48020:76;48091:4;48082:6;48020:76;:::i;:::-;48012:84;;47463:640;;;;;;;:::o;48109:141::-;48165:5;48196:6;48190:13;48181:22;;48212:32;48238:5;48212:32;:::i;:::-;48109:141;;;;:::o;48256:349::-;48325:6;48374:2;48362:9;48353:7;48349:23;48345:32;48342:119;;;48380:79;;:::i;:::-;48342:119;48500:1;48525:63;48580:7;48571:6;48560:9;48556:22;48525:63;:::i;:::-;48515:73;;48471:127;48256:349;;;;:::o
Swarm Source
ipfs://9721d7bfbcd8e5cd62de2691f6a2a8a01fe7c45a27a69ed2ddb20ff7c16b7833
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
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.