ERC-721
Overview
Max Total Supply
7,050 veKOI
Holders
4,989
Total Transfers
-
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
veKOI
Compiler Version
v0.8.17+commit.8df45f5f
ZkSolc Version
v1.3.14
Optimization Enabled:
Yes with Mode 3
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/governance/utils/Votes.sol"; //L-04 import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/utils/Checkpoints.sol"; import "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "../daov2/IVeVotes.sol"; /// @notice koi vote escrow, each individual veNFT can be delegated to a unique address contract veKOI is Context, Ownable2Step, EIP712, IVeVotes, ERC721Enumerable, ERC721URIStorage { using Strings for uint256; using Counters for Counters.Counter; using Checkpoints for Checkpoints.Trace224; Counters.Counter private _tokenIds; address public KoiToken; address public metaProxy; uint256 public voteSupply; address public conversionContract; // max & min lock time for vekoi uint256 public constant MAX_LOCK = 104 weeks; uint256 public constant MAX_LOCK_YEAR = 52 weeks; uint256 public constant MIN_LOCK = 1 weeks; struct UserLockInfo { uint256 amount; //koi locked uint256 time; // expiry time in unix uint256 vote_weight; // vote weight } //token id mapping to nft meta mapping(uint256 => UserLockInfo) private _nftLocks; /// @notice The EIP-712 typehash for the contract"s domain, m-03 bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 version,uint256 chainId,address verifyingContract)"); /// @notice The EIP-712 typehash for the delegation struct used by the contract bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(uint256 delegator,address delegatee,uint256 nonce,uint256 expiry)"); mapping(uint256 => address) private _delegation; /// @custom:oz-retyped-from mapping(address => Checkpoints.History) mapping(address => Checkpoints.Trace224) private _delegateCheckpoints; /// @custom:oz-retyped-from Checkpoints.History Checkpoints.Trace224 private _totalCheckpoints; mapping(address => Counters.Counter) private _nonces; uint8 private unlocked = 1; event LockEvent(address indexed from, address indexed to, uint256 lockAmount, uint256 mintedAmount, uint256 totalTime); event RedeemEvent(address indexed from, address indexed to, uint256 unlockedAmount, uint256 burnAmount); event SplitEvent(address indexed sender, address indexed owner, uint256 _oldTokenId, uint256 _tokenId1, uint256 _tokenId2); event MergeEvent(address indexed sender, address indexed owner_0, address owner_1, uint256 _tokenId0, uint256 _tokenId1, uint256 _newTokenId); event IncreaseLockEvent(address indexed sender, uint256 _tokenId, uint256 oldTime, uint256 newTime); /* ======== MODIFIERS ======== */ modifier nonReentrant() { require(unlocked == 1, "veKOI::ReentrancyGuard: REENTRANT_CALL"); unlocked = 0; _; unlocked = 1; } /* ======== OVERRIDE FUNCTIONS ======== */ function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } //info-12 function renounceOwnership() public override(Ownable) { return; } /** * @dev See {ERC721-_afterTokenTransfer}. Adjusts votes when tokens are transferred. * * Emits a {IVotes-DelegateVotesChanged} event. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { uint256 _voting_units = _nftLocks[firstTokenId].vote_weight; //keep track of total supply _transferVotingUnits(from, to, _voting_units, firstTokenId); super._afterTokenTransfer(from, to, firstTokenId, batchSize); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721Enumerable, ERC721URIStorage) returns (bool) { return super.supportsInterface(interfaceId); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { string memory output = IMetadataProxy(metaProxy).getMetadata( tokenId, _nftLocks[tokenId].amount, _nftLocks[tokenId].vote_weight, _nftLocks[tokenId].time); return output; } /* ======== CONSTRUCTOR ======== */ /// @dev Expects the koi token address, and a metadata proxy constructor (address _koiToken, address _metadata) ERC721("Vote Escrow KOI", "veKOI") EIP712("Vote Escrow KOI", "1") { KoiToken = _koiToken; metaProxy = _metadata; } /* ======== SETTERS ======== */ function changeMetadataProxy(address _metadata) public { require(msg.sender == owner(), "veKOI::changeMetadataProxy: INVALID_OWNER"); metaProxy = _metadata; } function setConversionContract(address _contract) public { require(msg.sender == owner(), "veKOI::setConversionContract: INVALID_OWNER"); conversionContract = _contract; } /* ======== INTERNAL FUNCTIONS ======== */ function mintToken(address owner, uint256 _amount, uint256 _amount_minted, uint256 _lock_time) internal { uint256 _id = _tokenIds.current(); //store meta before _afterTokenTransfer is called _nftLocks[_id] = UserLockInfo(_amount, _lock_time, _amount_minted); // m-04, non-reentrant is used on parent functions _safeMint(owner, _id); voteSupply += _amount_minted; _tokenIds.increment(); } function burnToken(uint256 _id) internal { _burn(_id); voteSupply -= _nftLocks[_id].vote_weight; } function timeToTokens(uint256 _amount, uint256 _lock_time) internal pure returns (uint256) { require(_lock_time >= MIN_LOCK, "veKOI::timeToTokens: UNDER_MIN_TIME"); require(_lock_time <= MAX_LOCK, "veKOI::timeToTokens: OVER_MAX_TIME"); // amount * % of time locked up from min to max uint256 base_tokens = (_amount * _lock_time) / MAX_LOCK_YEAR; return base_tokens; } /* ======== PUBLIC FUNCTIONS ======== */ function Lock(uint256 _amount, uint256 _lock_time) external { LockTo(_amount, _lock_time, msg.sender); } function LockTo(uint256 _amount, uint256 _lock_time, address to) public nonReentrant { require(IERC20(KoiToken).balanceOf(msg.sender) >= _amount, "veKOI::Lock: INSUFFICIENT_BALANCE"); //transfer tokens to this contract, m-05 require(IERC20(KoiToken).transferFrom(msg.sender, address(this), _amount), "veKOI::Lock: FAILED_TRANSFERFROM"); // calculate vote weight to mint uint256 tokens_to_mint = timeToTokens(_amount, _lock_time); require(tokens_to_mint > 0, "veKOI::Lock: INSUFFICIENT_TOKENS_MINTED"); // mint nft representation mintToken(to, _amount, tokens_to_mint, block.timestamp + _lock_time); emit LockEvent(msg.sender, to, _amount, tokens_to_mint, _lock_time); } function LockToAdmin(uint256 _amount, uint256 tokens_to_mint, uint256 _lock_time, address to) public nonReentrant { require(msg.sender == conversionContract, "veKOI::LockToAdmin: Invalid"); require(IERC20(KoiToken).balanceOf(msg.sender) >= _amount, "veKOI::LockToAdmin: INSUFFICIENT_BALANCE"); //transfer tokens to this contract, m-05 require(IERC20(KoiToken).transferFrom(msg.sender, address(this), _amount), "veKOI::LockToAdmin: FAILED_TRANSFERFROM"); // mint nft representation mintToken(to, _amount, tokens_to_mint, _lock_time); emit LockEvent(msg.sender, to, _amount, tokens_to_mint, _lock_time); } function Redeem(uint256[] memory lock_index) external { RedeemTo(lock_index, msg.sender); } function RedeemTo(uint256[] memory ids, address to) public nonReentrant { // info-07 require(to != address(0), "veKOI::Redeem: INVALID_ADDRESS"); uint256 total_to_redeem; uint256 total_to_burn; for(uint256 i = ids.length; i > 0; i--){ uint256 index = ids[i - 1]; UserLockInfo memory lock_info = _nftLocks[index]; require(msg.sender == ownerOf(index), "veKOI::Redeem: INVALID_OWNER"); require(block.timestamp >= lock_info.time, "veKOI::Redeem: INSUFFICIENT_LOCK_TIME"); require(lock_info.amount >= 0 , "veKOI::Redeem: INSUFFICIENT_AMOUNT"); require(lock_info.vote_weight >= 0 , "veKOI::Redeem: INSUFFICIENT_MINT_AMOUNT"); total_to_redeem = total_to_redeem + lock_info.amount; total_to_burn = total_to_burn + lock_info.vote_weight; //burn nft burnToken(index); } //voteSupply -= total_to_burn; //redeem tokens to user, m-05 require(IERC20(KoiToken).transfer(to, total_to_redeem), "veKOI::RedeemTo: FAILED_TRANSFER"); emit RedeemEvent(msg.sender, to, total_to_redeem, total_to_burn); } function IncreaseLockTime(uint256 _tokenId, uint256 _time) external nonReentrant { address sender = msg.sender; address owner = ownerOf(_tokenId); require(owner != address(0), "veKOI::IncreaseLockTime: OWNER_IS_ZERO"); require(_isApprovedOrOwner(sender, _tokenId), "veKOI::IncreaseLockTime: NOT_APPROVED_OWNER"); UserLockInfo memory lock_info = _nftLocks[_tokenId]; uint256 newLockTime = block.timestamp + _time; require(newLockTime >= lock_info.time, "veKOI::IncreaseLockTime: INSUFFICIENT_LOCK_TIME"); require(lock_info.vote_weight >= 0 , "veKOI::IncreaseLockTime: INSUFFICIENT_MINT_AMOUNT"); // calculate vote weight to mint uint256 tokens_to_mint = timeToTokens(lock_info.amount, _time); require(tokens_to_mint > 0, "veKOI::IncreaseLockTime: INSUFFICIENT_TOKENS_MINTED"); // make sure this lock is not smaller than the previous require(tokens_to_mint >= lock_info.vote_weight, "veKOI::IncreaseLockTime: INSUFFICIENT_LOCK_AMOUNT"); // burn current nft burnToken(_tokenId); // mint new nft // keep same underlying amount, update vote weight and expiry time mintToken(sender, lock_info.amount, tokens_to_mint, newLockTime); emit IncreaseLockEvent(sender, _tokenId, lock_info.time, newLockTime); } function Split(uint256 _tokenId, uint256 _amount) external nonReentrant returns (uint256 _tokenId1, uint256 _tokenId2) { address sender = msg.sender; address owner = ownerOf(_tokenId); require(owner != address(0), "veKOI::split: OWNER_IS_ZERO"); require(_isApprovedOrOwner(sender, _tokenId), "veKOI::split: NOT_APPROVED_OWNER"); UserLockInfo memory lock = _nftLocks[_tokenId]; require(lock.amount > _amount, "veKOI::split: INVALID_SPLIT_AMOUNT"); //info-6 require(_amount > 0, "veKOI::split: INVALID_SPLIT_AMOUNT_ZERO"); uint256 new_lock_expiry = lock.time; uint256 new_lock_amount_0 = _amount; uint256 new_lock_amount_1 = lock.amount - new_lock_amount_0; //require 10 koi min split L-03 uint256 new_lock_weight_0 = lock.vote_weight * _amount / lock.amount; uint256 new_lock_weight_1 = lock.vote_weight - new_lock_weight_0; // burn old veNFT burnToken(_tokenId); // Create new veNFT using old balance - amount _tokenId1 = _tokenIds.current(); mintToken(sender, new_lock_amount_0, new_lock_weight_0, new_lock_expiry); // Create new veNFT using amount _tokenId2 = _tokenIds.current(); mintToken(sender, new_lock_amount_1, new_lock_weight_1, new_lock_expiry); emit SplitEvent(sender, owner, _tokenId, _tokenId1, _tokenId2); } function Merge(uint256 _tokenId0, uint256 _tokenId1) external nonReentrant returns (uint256 _newTokenId) { address sender = msg.sender; address owner_0 = ownerOf(_tokenId0); address owner_1 = ownerOf(_tokenId1); require(_tokenId0 != _tokenId1, "veKOI::Merge: SAME_TOKENID"); require(owner_0 != address(0), "veKOI::Merge: OWNER1_IS_ZERO"); require(owner_1 != address(0), "veKOI::Merge: OWNER2_IS_ZERO"); require(_isApprovedOrOwner(sender, _tokenId0), "veKOI::Merge: NOT_APPROVED_OWNER"); require(_isApprovedOrOwner(sender, _tokenId1), "veKOI::Merge: NOT_APPROVED_OWNER"); UserLockInfo memory lock_0 = _nftLocks[_tokenId0]; UserLockInfo memory lock_1 = _nftLocks[_tokenId1]; // use the larger lock time uint256 new_lock_expiry = (lock_0.time > lock_1.time ? lock_0.time : lock_1.time); // add locked amounts uint256 new_lock_amount = lock_0.amount + lock_1.amount; // add vote weight amounts uint256 new_lock_weight = lock_0.vote_weight + lock_1.vote_weight; // burn old veNFTs burnToken(_tokenId0); burnToken(_tokenId1); // Create new veNFT using old balance - amount _newTokenId = _tokenIds.current(); mintToken(sender, new_lock_amount, new_lock_weight, new_lock_expiry); emit MergeEvent(sender, owner_0, owner_1, _tokenId0, _tokenId1, _newTokenId); } /* ======== VIEW FUNCTIONS ======== */ function GetMintCount() public view returns(uint256 _count) { _count = _tokenIds.current(); } function GetLockInfo(uint256 _id) public view returns(UserLockInfo memory _info) { return _nftLocks[_id]; } /** * @dev Returns the total koi token balance of all NFTs in `account`. */ function GetUnderlyingTokens(address account) public view returns(uint256 amount) { uint256 bal = balanceOf(account); uint256 _koi_bal; for(uint256 i; i < bal; i++){ uint256 _token = tokenOfOwnerByIndex(account, i); _koi_bal += _nftLocks[_token].amount; } return _koi_bal; } /** * @dev Returns the total vote weight balance of all NFTs in `account`. */ function GetVotingTokens(address account) public view returns(uint256 amount) { uint256 bal = balanceOf(account); uint256 _koi_bal; for(uint256 i; i < bal; i++){ uint256 _token = tokenOfOwnerByIndex(account, i); uint256 vote_bal = _nftLocks[_token].vote_weight; _koi_bal += vote_bal; } return _koi_bal; } /* ======== DAO FUNCTIONS ======== */ /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() public view virtual returns (uint48) { return SafeCast.toUint48(block.timestamp); } /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual returns (string memory) { // Check that the clock was not modified require(clock() == block.timestamp, "ERC20Votes: broken clock mode"); return "mode=timestamp&from=default"; } /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) public view virtual override returns (uint256) { return _delegateCheckpoints[account].latest(); } /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * Requirements: * * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined. */ function getPastVotes(address account, uint256 timepoint) public view virtual override returns (uint256) { require(timepoint < clock(), "veKOI::getPastVotes: future lookup"); return _delegateCheckpoints[account].upperLookupRecent(SafeCast.toUint32(timepoint)); } /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. * * Requirements: * * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined. */ function getPastTotalSupply(uint256 timepoint) public view virtual override returns (uint256) { require(timepoint < clock(), "veKOI::getPastTotalSupply: FUTURE_LOOKUP"); return _totalCheckpoints.upperLookupRecent(SafeCast.toUint32(timepoint)); } /** * @dev Returns the current total supply of votes. */ function _getTotalSupply() internal view virtual returns (uint256) { return _totalCheckpoints.latest(); } /** * @dev Returns the delegate that `account` has chosen. */ function delegates(uint256 tokenId) public view virtual override returns (address) { address _del = _delegation[tokenId]; // auto delegate to self //if(_del == address(0)) //return ownerOf(tokenId); return _del; } /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(uint256 tokenId, address delegatee) public virtual override nonReentrant { address account = msg.sender; require(_isApprovedOrOwner(account, tokenId), "veKOI::delegate: INVALID_OWNER"); _delegate(tokenId, delegatee); } /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig( uint256 delegator, address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external nonReentrant { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "veKOI::delegateBySig: MALLEABLE_ERROR"); bytes32 domainSeparator = keccak256( abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name())), keccak256(bytes("1")), block.chainid, address(this)) ); bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegator, delegatee, nonce, expiry)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); address signatory = ecrecover(digest, v, r, s); require(_isApprovedOrOwner(signatory, delegator), "veKOI::delegateBySig: INVALID_OWNER"); require(signatory != address(0), "veKOI::delegateBySig: INVALID_ADDRESS"); require(nonce == _useNonce(signatory), "veKOI::delegateBySig: INVALID_NONCE"); require(block.timestamp <= expiry, "veKOI::delegateBySig: EXPIRED"); return _delegate(delegator, delegatee); } /** * @dev Delegate all of `account`'s voting units to `delegatee`. * * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. */ function _delegate(uint256 tokenId, address delegatee) internal virtual { address oldDelegate = delegates(tokenId); _delegation[tokenId] = delegatee; emit DelegateChanged(oldDelegate, tokenId, delegatee); _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(tokenId)); } /** * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to` * should be zero. Total supply of voting units will be adjusted with mints and burns. */ function _transferVotingUnits(address from, address to, uint256 amount, uint256 tokenId) internal virtual { // minted nft if (from == address(0)) { _push(_totalCheckpoints, _add, SafeCast.toUint224(amount)); //assign delegate to owner and mint delegated votes _delegation[tokenId] = to; _moveDelegateVotes(address(0), to, amount); } // burned nft if (to == address(0)) { _push(_totalCheckpoints, _subtract, SafeCast.toUint224(amount)); //burn delegated votes _moveDelegateVotes(delegates(tokenId), address(0), amount); } //_moveDelegateVotes(delegates(from), delegates(to), amount); } /** * @dev Moves delegated votes from one delegate to another. */ function _moveDelegateVotes(address from, address to, uint256 amount) private { if (from != to && amount > 0) { if (from != address(0)) { (uint256 oldValue, uint256 newValue) = _push( _delegateCheckpoints[from], _subtract, SafeCast.toUint224(amount) ); emit DelegateVotesChanged(from, oldValue, newValue); } if (to != address(0)) { (uint256 oldValue, uint256 newValue) = _push( _delegateCheckpoints[to], _add, SafeCast.toUint224(amount) ); emit DelegateVotesChanged(to, oldValue, newValue); } } } function _push( Checkpoints.Trace224 storage store, function(uint224, uint224) view returns (uint224) op, uint224 delta ) private returns (uint224, uint224) { return store.push(SafeCast.toUint32(clock()), op(store.latest(), delta)); } function _add(uint224 a, uint224 b) private pure returns (uint224) { return a + b; } function _subtract(uint224 a, uint224 b) private pure returns (uint224) { return a - b; } /** * @dev Consumes a nonce. * * Returns the current value and increments nonce. */ function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } /** * @dev Returns an address nonce. */ function nonces(address owner) public view virtual returns (uint256) { return _nonces[owner].current(); } /** * @dev Returns the contract's {EIP712} domain separator. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32) { return _domainSeparatorV4(); } function _getVotingUnits(uint256 tokenId) internal view virtual returns (uint256) { return _nftLocks[tokenId].vote_weight; } } interface IMetadataProxy { function getMetadata(uint256 _tokenId, uint256 amount_locked, uint256 amount_minted, uint256 end_time) external view returns (string memory output); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @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. 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./Ownable.sol"; /** * @dev Contract module which provides 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} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.0; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. */ function getPastVotes(address account, uint256 timepoint) external view returns (uint256); /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 timepoint) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/Votes.sol) pragma solidity ^0.8.0; import "../../interfaces/IERC5805.sol"; import "../../utils/Context.sol"; import "../../utils/Counters.sol"; import "../../utils/Checkpoints.sol"; import "../../utils/cryptography/EIP712.sol"; /** * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of * "representative" that will pool delegated voting units from different accounts and can then use it to vote in * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative. * * This contract is often combined with a token contract such that voting units correspond to token units. For an * example, see {ERC721Votes}. * * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the * cost of this history tracking optional. * * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the * previous example, it would be included in {ERC721-_beforeTokenTransfer}). * * _Available since v4.5._ */ abstract contract Votes is Context, EIP712, IERC5805 { using Checkpoints for Checkpoints.Trace224; using Counters for Counters.Counter; bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); mapping(address => address) private _delegation; /// @custom:oz-retyped-from mapping(address => Checkpoints.History) mapping(address => Checkpoints.Trace224) private _delegateCheckpoints; /// @custom:oz-retyped-from Checkpoints.History Checkpoints.Trace224 private _totalCheckpoints; mapping(address => Counters.Counter) private _nonces; /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based * checkpoints (and voting), in which case {CLOCK_MODE} should be overridden as well to match. */ function clock() public view virtual override returns (uint48) { return SafeCast.toUint48(block.number); } /** * @dev Machine-readable description of the clock as specified in EIP-6372. */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual override returns (string memory) { // Check that the clock was not modified require(clock() == block.number, "Votes: broken clock mode"); return "mode=blocknumber&from=default"; } /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) public view virtual override returns (uint256) { return _delegateCheckpoints[account].latest(); } /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * Requirements: * * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined. */ function getPastVotes(address account, uint256 timepoint) public view virtual override returns (uint256) { require(timepoint < clock(), "Votes: future lookup"); return _delegateCheckpoints[account].upperLookupRecent(SafeCast.toUint32(timepoint)); } /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. * * Requirements: * * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined. */ function getPastTotalSupply(uint256 timepoint) public view virtual override returns (uint256) { require(timepoint < clock(), "Votes: future lookup"); return _totalCheckpoints.upperLookupRecent(SafeCast.toUint32(timepoint)); } /** * @dev Returns the current total supply of votes. */ function _getTotalSupply() internal view virtual returns (uint256) { return _totalCheckpoints.latest(); } /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) public view virtual override returns (address) { return _delegation[account]; } /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) public virtual override { address account = _msgSender(); _delegate(account, delegatee); } /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= expiry, "Votes: signature expired"); address signer = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s ); require(nonce == _useNonce(signer), "Votes: invalid nonce"); _delegate(signer, delegatee); } /** * @dev Delegate all of `account`'s voting units to `delegatee`. * * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. */ function _delegate(address account, address delegatee) internal virtual { address oldDelegate = delegates(account); _delegation[account] = delegatee; emit DelegateChanged(account, oldDelegate, delegatee); _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account)); } /** * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to` * should be zero. Total supply of voting units will be adjusted with mints and burns. */ function _transferVotingUnits(address from, address to, uint256 amount) internal virtual { if (from == address(0)) { _push(_totalCheckpoints, _add, SafeCast.toUint224(amount)); } if (to == address(0)) { _push(_totalCheckpoints, _subtract, SafeCast.toUint224(amount)); } _moveDelegateVotes(delegates(from), delegates(to), amount); } /** * @dev Moves delegated votes from one delegate to another. */ function _moveDelegateVotes(address from, address to, uint256 amount) private { if (from != to && amount > 0) { if (from != address(0)) { (uint256 oldValue, uint256 newValue) = _push( _delegateCheckpoints[from], _subtract, SafeCast.toUint224(amount) ); emit DelegateVotesChanged(from, oldValue, newValue); } if (to != address(0)) { (uint256 oldValue, uint256 newValue) = _push( _delegateCheckpoints[to], _add, SafeCast.toUint224(amount) ); emit DelegateVotesChanged(to, oldValue, newValue); } } } function _push( Checkpoints.Trace224 storage store, function(uint224, uint224) view returns (uint224) op, uint224 delta ) private returns (uint224, uint224) { return store.push(SafeCast.toUint32(clock()), op(store.latest(), delta)); } function _add(uint224 a, uint224 b) private pure returns (uint224) { return a + b; } function _subtract(uint224 a, uint224 b) private pure returns (uint224) { return a - b; } /** * @dev Consumes a nonce. * * Returns the current value and increments nonce. */ function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } /** * @dev Returns an address nonce. */ function nonces(address owner) public view virtual returns (uint256) { return _nonces[owner].current(); } /** * @dev Returns the contract's {EIP712} domain separator. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32) { return _domainSeparatorV4(); } /** * @dev Must return the voting units held by an account. */ function _getVotingUnits(address) internal view virtual returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4906.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; import "./IERC721.sol"; /// @title EIP-721 Metadata Update Extension interface IERC4906 is IERC165, IERC721 { /// @dev This event emits when the metadata of a token is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFT. event MetadataUpdate(uint256 _tokenId); /// @dev This event emits when the metadata of a range of tokens is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFTs. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.0; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5805.sol) pragma solidity ^0.8.0; import "../governance/utils/IVotes.sol"; import "./IERC6372.sol"; interface IERC5805 is IERC6372, IVotes {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC6372.sol) pragma solidity ^0.8.0; interface IERC6372 { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.0; import "../token/ERC721/IERC721.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @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 (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; import "../ERC721.sol"; import "./IERC721Enumerable.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/extensions/ERC721URIStorage.sol) pragma solidity ^0.8.0; import "../ERC721.sol"; import "../../../interfaces/IERC4906.sol"; /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is IERC4906, ERC721 { using Strings for uint256; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; /** * @dev See {IERC165-supportsInterface} */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) { return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = _baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } return super.tokenURI(tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Emits {MetadataUpdate}. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; emit MetadataUpdate(tokenId); } /** * @dev See {ERC721-_burn}. This override additionally checks to see if a * token-specific URI was set for the token, and if so, it deletes the token URI from * the storage mapping. */ function _burn(uint256 tokenId) internal virtual override { super._burn(tokenId); if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // 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); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Checkpoints.sol) // This file was procedurally generated from scripts/generate/templates/Checkpoints.js. pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SafeCast.sol"; /** * @dev This library defines the `History` struct, for checkpointing values as they change at different points in * time, and later looking up past values by block number. See {Votes} as an example. * * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new * checkpoint for the current transaction block using the {push} function. * * _Available since v4.5._ */ library Checkpoints { struct History { Checkpoint[] _checkpoints; } struct Checkpoint { uint32 _blockNumber; uint224 _value; } /** * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the * block, the requested block number must be in the past, excluding the current block. */ function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { require(blockNumber < block.number, "Checkpoints: block not yet mined"); uint32 key = SafeCast.toUint32(blockNumber); uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of * checkpoints. */ function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { require(blockNumber < block.number, "Checkpoints: block not yet mined"); uint32 key = SafeCast.toUint32(blockNumber); uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block. * * Returns previous value and new value. */ function push(History storage self, uint256 value) internal returns (uint256, uint256) { return _insert(self._checkpoints, SafeCast.toUint32(block.number), SafeCast.toUint224(value)); } /** * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will * be set to `op(latest, delta)`. * * Returns previous value and new value. */ function push( History storage self, function(uint256, uint256) view returns (uint256) op, uint256 delta ) internal returns (uint256, uint256) { return push(self, op(latest(self), delta)); } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(History storage self) internal view returns (uint224) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint( History storage self ) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._blockNumber, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(History storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._blockNumber <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._blockNumber == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint({_blockNumber: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint({_blockNumber: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._blockNumber > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._blockNumber < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace224 { Checkpoint224[] _checkpoints; } struct Checkpoint224 { uint32 _key; uint224 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint. * * Returns previous value and new value. */ function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none. */ function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. */ function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys). */ function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace224 storage self) internal view returns (uint224) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace224 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint224 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._key <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint224({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint224({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint224[] storage self, uint256 pos ) private pure returns (Checkpoint224 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace160 { Checkpoint160[] _checkpoints; } struct Checkpoint160 { uint96 _key; uint160 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint. * * Returns previous value and new value. */ function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none. */ function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. */ function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys). */ function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace160 storage self) internal view returns (uint160) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace160 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint160 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._key <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint160({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint160({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint160[] storage self, uint256 pos ) private pure returns (Checkpoint160 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } }
// SPDX-License-Identifier: MIT // 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol) pragma solidity ^0.8.8; import "./StorageSlot.sol"; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(_FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } }
// SPDX-License-Identifier: MIT // 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 } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; import "./ECDSA.sol"; import "../ShortStrings.sol"; import "../../interfaces/IERC5267.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. * * _Available since v4.9._ */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; /// Modified IVotes interface for tokenId based voting interface IVeVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, uint256 indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. */ function getPastVotes(address account, uint256 timepoint) external view returns (uint256); /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 timepoint) external view returns (uint256); /** * @dev Returns the delegate that `tokenId` has chosen. Can never be equal to the delegator's `tokenId`. * Returns 0 if not delegated. */ function delegates(uint256 tokenId) external view returns (address); /** * @dev Delegates votes from the tokenId to `delegatee`. */ function delegate(uint256 tokenId, address delegatee) external; /** * @dev Delegates votes from `delegator` to `delegatee`. Signer must own `delegator`. */ function delegateBySig( uint256 delegator, address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; }
{ "areLibrariesMissing": false, "compilerPath": "/Users/matthew/Library/Caches/hardhat-nodejs/compilers-v2/zksolc/zksolc-v1.3.14", "experimental": {}, "isSystem": false, "libraries": {}, "missingLibrariesPath": "./.zksolc-libraries-cache/missingLibraryDependencies.json", "optimizer": { "enabled": true, "mode": "3" }, "outputSelection": { "*": { "*": [ "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_koiToken","type":"address"},{"internalType":"address","name":"_metadata","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","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":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"uint256","name":"fromDelegate","type":"uint256"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTime","type":"uint256"}],"name":"IncreaseLockEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"lockAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalTime","type":"uint256"}],"name":"LockEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"owner_0","type":"address"},{"indexed":false,"internalType":"address","name":"owner_1","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tokenId1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTokenId","type":"uint256"}],"name":"MergeEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"unlockedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"burnAmount","type":"uint256"}],"name":"RedeemEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_oldTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tokenId1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tokenId2","type":"uint256"}],"name":"SplitEvent","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"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DELEGATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"GetLockInfo","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"uint256","name":"vote_weight","type":"uint256"}],"internalType":"struct veKOI.UserLockInfo","name":"_info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GetMintCount","outputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"GetUnderlyingTokens","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"GetVotingTokens","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_time","type":"uint256"}],"name":"IncreaseLockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"KoiToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_lock_time","type":"uint256"}],"name":"Lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_lock_time","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"LockTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"tokens_to_mint","type":"uint256"},{"internalType":"uint256","name":"_lock_time","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"LockToAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"MAX_LOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LOCK_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_LOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId0","type":"uint256"},{"internalType":"uint256","name":"_tokenId1","type":"uint256"}],"name":"Merge","outputs":[{"internalType":"uint256","name":"_newTokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"lock_index","type":"uint256[]"}],"name":"Redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"RedeemTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Split","outputs":[{"internalType":"uint256","name":"_tokenId1","type":"uint256"},{"internalType":"uint256","name":"_tokenId2","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_metadata","type":"address"}],"name":"changeMetadataProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conversionContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"delegator","type":"uint256"},{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metaProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"pendingOwner","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setConversionContract","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"voteSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
9c4d535b000000000000000000000000000000000000000000000000000000000000000001000def079683ac07e6f9bcd2a9ee692d23d577c18c94dfecd6f584df366d4600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a995ad25ce5eb76972ab356168f5e1d9257e4d05000000000000000000000000d38ebb608da8b4a9e75bb5a77dcf437ad423938c
Deployed Bytecode
0x000400000000000200110000000000020000000003010019000000600330027000000ceb043001970003000000410355000200000001035500000ceb0030019d000100000000001f00000001012001900000003d0000c13d0000008001000039000000400010043f0000000001000031000000040110008c0000007e0000413d0000000201000367000000000101043b000000e00110027000000cfd0210009c000000800000a13d00000cfe0210009c0000008d0000213d00000d120210009c000000d50000213d00000d1c0210009c000001ff0000a13d00000d1d0210009c0000030d0000213d00000d200210009c000003b60000613d00000d210110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000001101000039000000000101041a00000cee01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d00000000010000310000017f02100039000000200400008a000000000242016f00000cec0320009c0000004c0000413d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430001100000004001d000000400020043f0000001f0210018f000000020300036700000005041002720000005b0000613d00000000050000190000000506500210000000000763034f000000000707043b000001600660003900000000007604350000000105500039000000000645004b000000530000413d000000000502004b0000006a0000613d0000000504400210000000000343034f00000003022002100000016004400039000000000504043300000000052501cf000000000525022f000000000303043b0000010002200089000000000323022f00000000022301cf000000000252019f000000000024043500000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000001600100043d001000000001001d00000cee0110009c0000007e0000213d000001800100043d000f00000001001d00000cee0110009c000001540000a13d0000000001000019000033aa0001043000000d250210009c000000b90000a13d00000d260210009c000001030000213d00000d300210009c000002060000a13d00000d310210009c0000032c0000213d00000d340210009c000003db0000613d00000d350110009c0000007e0000c13d33a813a00000040f00000cff0210009c000001250000213d00000d090210009c0000021f0000a13d00000d0a0210009c000003530000213d00000d0d0210009c000003dc0000613d00000d0e0110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b00000cee0210009c0000007e0000213d000000000200041a00000cee022001970000000003000411000000000223004b000006f30000c13d0000001302000039000000000302041a00000cf303300197000000000113019f000000000012041b0000000001000019000033a90001042e00000d390210009c0000012e0000a13d00000d3a0210009c000002640000a13d00000d3b0210009c000003580000213d00000d3e0210009c000004450000613d00000d3f0110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000000100003133a80f4f0000040f001100000001001d001000000002001d0000000002030019000f00000002001d000000000100041133a822900000040f33a821c40000040f000000110100002900000010020000290000000f0300002933a823060000040f0000000001000019000033a90001042e00000d130210009c0000026b0000a13d00000d140210009c0000037d0000213d00000d170210009c0000045f0000613d00000d180110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b00000cee0210009c0000007e0000213d00000000001004350000001601000039000000200010043f0000004002000039000000000100001933a809a00000040f33a82e570000040f00000d5801100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e00000d270210009c000002930000a13d00000d280210009c000003820000213d00000d2b0210009c0000048f0000613d00000d2c0110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000000400100043d00000d6502000041000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4b011001c7000033a90001042e00000d000210009c000002b70000a13d00000d010210009c000003980000213d00000d040210009c000004900000613d00000d050110009c0000007e0000c13d33a820580000040f00000d430210009c000002ec0000213d00000d470210009c000004ac0000613d00000d480210009c000004d80000613d00000d490110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b33a8218b0000040f00000cee01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e000000400600043d00000cef0160009c000000460000213d0000004001600039000000400010043f0000000f01000039000000000716043600000cf0020000410000000000270435000000400400043d00000cef0240009c000000460000213d0000004002400039000000400020043f0000000503000039000000000534043600000cf1020000410000000000250435000000400900043d00000cef0290009c000000460000213d0000004002900039000000400020043f000000000219043600000cf0010000410000000000120435000000400800043d00000cef0180009c000000460000213d000c00000002001d000e00000009001d000600000007001d000900000006001d000400000005001d000700000004001d000800000003001d0000004001800039000000400010043f000000200280003900000cf201000041000b00000002001d00000000001204350000000102000039000d00000008001d0000000000280435000000000102041a00000cf301100197000500000002001d000000000012041b0000000006000411000000000200041a00000cf301200197000000000161019f000000000010041b00000ceb01000041000000000300041400000ceb0430009c0000000001034019000000c00110021000000cf4011001c700000cee052001970000800d02000039000000030300003900000cf504000041000a00000003001d33a8339e0000040f00000001012001900000007e0000613d0000000e040000290000000006040433000000200160008c0000076c0000413d00000cf60160009c000000460000213d0000000201000039000300000001001d000000000101041a000000010210019000000001011002700000007f0310018f000000000301c0190000001f0130008c00000000010000190000000101002039000000010110018f000000000112004b000004f60000c13d000200000006001d000100000003001d000000200130008c000001ca0000413d0000000301000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d000000000201043b00000002010000290000001f011000390000000501100270000000000112001900000001030000290000001f0330003900000005033002700000000002320019000000000321004b000001ca0000813d000000000001041b0000000101100039000000000321004b000001c60000413d0000000301000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d0000001102000029000000020300002900000000032301700000002002000039000000000101043b0000000e06000029000001e70000613d0000002002000039000000000400001900000000056200190000000005050433000000000051041b000000200220003900000001011000390000002004400039000000000534004b000001df0000413d0000000204000029000000000343004b000001f50000813d00000002030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f0000000e0400002900000000024200190000000002020433000000000232016f000000000021041b0000000201000029000000010110021000000001011001bf0000000302000029000000000012041b000000ff010000390000000d020000290000000e040000290000000c050000290000077a0000013d00000d220210009c000004fc0000613d00000d230210009c000004fd0000613d00000d240110009c0000007e0000c13d33a818750000040f00000d360210009c000005280000613d00000d370210009c000005420000613d00000d380110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000000100003133a80f4f0000040f001100000001001d001000000002001d000f00000003001d000000400100043d000e00000001001d33a80b410000040f0000000e040000290000000000040435000000110100002900000010020000290000000f0300002933a821dc0000040f0000000001000019000033a90001042e00000d0f0210009c000005430000613d00000d100210009c000005670000613d00000d110110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000000400100043d001100000001001d33a80b2b0000040f00000011020000290000004001200039000000000001043500000020012000390000000000010435000000000002043500000004010000390000000201100367000000000101043b00000000001004350000001401000039000000200010043f0000004002000039000000000100001933a809a00000040f001100000001001d000000400100043d001000000001001d33a80b2b0000040f0000001104000029000000000104041a000000100500002900000000021504360000000103400039000000000303041a000000000032043500000040035000390000000204400039000000000404041a0000000000430435000000400400043d00000000011404360000000002020433000000000021043500000000010304330000004002400039000000000012043500000ceb0100004100000ceb0240009c0000000001044019000000400110021000000d57011001c7000033a90001042e00000d400210009c000005680000613d00000d410210009c000005690000613d00000d420110009c0000007e0000c13d33a80d570000040f00000d190210009c000005840000613d00000d1a0210009c000005bd0000613d00000d1b0110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b00000cee0210009c0000007e0000213d000000000200041a00000cee022001970000000003000411000000000223004b000007080000c13d0000001102000039000000000302041a00000cf303300197000000000113019f000000000012041b0000000001000019000033a90001042e00000d2d0210009c000005dd0000613d00000d2e0210009c000005f90000613d00000d2f0110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b33a8214d0000040f00000cee01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e00000d060210009c000006140000613d00000d070210009c000006300000613d00000d080110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000002020003670000000401200370000000000101043b00000cee0310009c0000007e0000213d0000002402200370000000000202043b001100000002001d00000cee0220009c0000007e0000213d00000000001004350000000901000039000000200010043f0000004002000039000000000100001933a809a00000040f000000110200002933a821130000040f000000000101041a000000ff011001900000000001000019000000010100c039000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e00000d440210009c0000064a0000613d00000d450210009c0000064b0000613d00000d460110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000000f01000039000000000101041a000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e00000d1e0210009c0000064c0000613d00000d1f0110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000000000100041a00000cee01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e00000d320210009c0000064d0000613d00000d330110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b0000000c02000039000000000302041a000000000331004b000006b70000813d000000000020043500000d6801100041000000000101041a000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e00000d0b0210009c0000064e0000613d00000d0c0110009c0000007e0000c13d33a81f440000040f00000d3c0210009c000006680000613d00000d3d0110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000002020003670000000401200370000000000101043b00000cee0310009c0000007e0000213d0000002402200370000000000202043b33a826f80000040f000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e00000d150210009c000006690000613d00000d160110009c0000007e0000c13d33a81d5e0000040f00000d290210009c0000066a0000613d00000d2a0110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000006b50000013d00000d020210009c000006890000613d00000d030110009c0000007e0000c13d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000000400100043d00000d4a02000041000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b00000cee0210009c0000007e0000213d00000000001004350000001801000039000000200010043f0000004002000039000000000100001933a809a00000040f000000000101041a000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e33a811b50000040f0000000001000416000000000101004b0000007e0000c13d0000000003000031000000040130008a00000ced02000041000000800410008c0000000004000019000000000402401900000ced01100197000000000501004b000000000200a01900000ced0110009c00000000010400190000000001026019000000000101004b0000007e0000c13d00000002040003670000000401400370000000000101043b00000cee0210009c0000007e0000213d0000002402400370000000000202043b00000cee0520009c0000007e0000213d0000006405400370000000000605043b00000cf60560009c0000007e0000213d000000230560003900000ced07000041000000000835004b0000000008000019000000000807801900000ced0330019700000ced05500197000000000935004b0000000007008019000000000335013f00000ced0330009c00000000030800190000000003076019000000000303004b0000007e0000c13d0000000403600039000000000334034f000000000303043b00000cf60430009c000000460000213d0000003f04300039000000200500008a000000000554016f000000400400043d0000000005540019000000000745004b0000000007000019000000010700403900000cf60850009c000000460000213d0000000107700190000000460000c13d000000400050043f0000000005340436000000240760003900000000067300190000000008000031000000000686004b0000007e0000213d0000001f0630018f000000020770036700000005083002720000042e0000613d0000000009000019000000050a900210000000000ba50019000000000aa7034f000000000a0a043b0000000000ab04350000000109900039000000000a89004b000004260000413d000000000906004b0000043d0000613d0000000508800210000000000787034f00000000088500190000000306600210000000000908043300000000096901cf000000000969022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000696019f00000000006804350000000003350019000000000003043500000044030000390000000203300367000000000303043b33a821dc0000040f0000000001000019000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000000400100043d00000d6902000041000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000000504000039000000000304041a000000010530019000000001013002700000007f0210018f000000000701001900000000070260190000001f0270008c00000000020000190000000102002039000000000223013f0000000102200190000004f60000c13d000000400100043d0000000002710436000000000505004b0000071d0000613d0000000000400435000000000307004b0000000003000019000007230000613d00000d590400004100000000030000190000000005320019000000000604041a000000000065043500000001044000390000002003300039000000000573004b000004870000413d000007230000013d33a814cc0000040f0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000001001000039000000000101041a00000cee01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b00000d6b02100197000000000212004b0000007e0000c13d000000010200003900000d6c0310009c000004cf0000613d00000d6d0310009c000004cf0000613d00000d6e0310009c000004cf0000613d00000d6f0310009c000004cf0000613d00000d700110009c00000000020000190000000102006039000000010120018f000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000000404000039000000000304041a000000010530019000000001013002700000007f0210018f000000000701001900000000070260190000001f0270008c00000000020000190000000102002039000000000223013f0000000102200190000006cc0000613d00000d550100004100000000001004350000002201000039000000040010043f00000d5601000041000033aa0001043033a8168b0000040f0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000000101000039000000000201041a00000cee032001970000000006000411000000000363004b000006de0000c13d00000cf302200197000000000021041b000000000200041a00000cf301200197000000000161019f000000000010041b00000ceb01000041000000000300041400000ceb0430009c0000000001034019000000c00110021000000cf4011001c700000cee052001970000800d02000039000000030300003900000cf50400004133a8339e0000040f0000000101200190000006b50000c13d0000007e0000013d0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d33a832ed0000040f000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e33a811460000040f0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b00000000001004350000001501000039000000200010043f0000004002000039000000000100001933a809a00000040f000000000101041a00000cee01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e33a81dce0000040f33a80b5f0000040f0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000000c01000039000000000101041a000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b001100000001001d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f00000001022001900000007e0000613d000000000301043b00000d5e0230009c000007350000413d000000400100043d000000640210003900000d61030000410000000000320435000000440210003900000d6203000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000d5c0100004100000000001004390000800b01000039000000040200003933a809b60000040f33a82e3f0000040f00000d5d01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000001301000039000000000101041a00000cee01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000001201000039000000000101041a000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d0000000101000039000000000101041a00000cee01100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000000400100043d00000d5002000041000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4b011001c7000033a90001042e33a809dd0000040f33a80aa90000040f33a81a2c0000040f33a814120000040f0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d000000400100043d00000d5102000041000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4b011001c7000033a90001042e33a80f6a0000040f33a81b6a0000040f0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000101043b00000cee0210009c0000007e0000213d33a821240000040f000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e0000000001000416000000000101004b0000007e0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000007e0000c13d00000004010000390000000201100367000000000601043b00000cee0160009c0000007e0000213d000000000100041a00000cee011001970000000005000411000000000151004b000007430000c13d0000000101000039000000000201041a00000cf302200197000000000262019f000000000021041b00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf4011001c70000800d02000039000000030300003900000d4f0400004133a8339e0000040f00000001012001900000007e0000613d0000000001000019000033a90001042e000000400100043d000000640210003900000d66030000410000000000320435000000440210003900000d6703000041000000000032043500000024021000390000002c03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d0000000002710436000000000505004b000007540000613d0000000000400435000000000307004b00000000030000190000075a0000613d00000d6a0400004100000000030000190000000005320019000000000604041a000000000065043500000001044000390000002003300039000000000573004b000006d60000413d0000075a0000013d000000400100043d000000640210003900000d63030000410000000000320435000000440210003900000d6403000041000000000032043500000024021000390000002903000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000d52030000410000000000320435000000440210003900000d5303000041000000000032043500000024021000390000002b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000d5a030000410000000000320435000000440210003900000d5b03000041000000000032043500000024021000390000002903000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000001000400008a000000000343016f0000000000320435000000000207004b000000200300003900000000030060190000002002300039001100000001001d33a80b4c0000040f000000400100043d001000000001001d000000110200002933a809c70000040f0000001004000029000000000141004900000ceb0200004100000ceb0310009c000000000102801900000ceb0340009c000000000204401900000040022002100000006001100210000000000121019f000033a90001042e0000001101000029000000000231004b000007e00000813d33a82fd60000040f33a82e720000040f00000d5801100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e000000400100043d000000440210003900000d4c03000041000000000032043500000d4d0200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000001000400008a000000000343016f0000000000320435000000000207004b000000200300003900000000030060190000002002300039001100000001001d33a80b4c0000040f000000400100043d001000000001001d000000110200002933a809c70000040f0000001004000029000000000141004900000ceb0200004100000ceb0310009c000000000102801900000ceb0340009c000000000204401900000040022002100000006001100210000000000121019f000033a90001042e00000003016002100000010002100089000000010300008a00000000022301cf0000000001100049000001000300008a000000000131004b000000000102001900000000010040190000000c050000290000000002050433000000000112016f000000000161019f0000000d02000029000001200010043f0000000006020433000000200160008c000007f50000413d00000cf60160009c000000460000213d000300000006001d0000000a01000029000000000101041a000000010210019000000001021002700000007f0320018f0000000002036019000200000002001d0000001f0220008c00000000020000190000000102002039000000000121013f0000000101100190000004f60000c13d0000000201000029000000200110008c000007ac0000413d0000000a01000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d000000000201043b00000003010000290000001f011000390000000501100270000000000112001900000002030000290000001f0330003900000005033002700000000002320019000000000321004b000007ac0000813d000000000001041b0000000101100039000000000321004b000007a80000413d0000000a01000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d0000001102000029000000030300002900000000032301700000002002000039000000000101043b0000000d06000029000007c90000613d0000002002000039000000000400001900000000056200190000000005050433000000000051041b000000200220003900000001011000390000002004400039000000000534004b000007c10000413d0000000304000029000000000343004b000007d70000813d00000003030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f0000000d0400002900000000024200190000000002020433000000000232016f000000000021041b0000000301000029000000010110021000000001011001bf0000000a02000029000000000012041b000000ff010000390000000e040000290000000c05000029000008020000013d000000400100043d000000640210003900000d5f030000410000000000320435000000440210003900000d6003000041000000000032043500000024021000390000002803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000003016002100000010002100089000000010300008a00000000022301cf0000000001100049000001000300008a000000000131004b000000000102001900000000010040190000000b020000290000000002020433000000000112016f000000000161019f000001400010043f00000ceb0100004100000ceb0250009c000000000201001900000000020540190000004002200210000000000304043300000ceb0430009c00000000030180190000006003300210000000000223019f000000000300041400000ceb0430009c0000000001034019000000c001100210000000000121019f00000cf4011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d000000000101043b000e00000001001d000000e00010043f00000ceb010000410000000b0300002900000ceb0230009c0000000002010019000000000203401900000040022002100000000d03000029000000000303043300000ceb0430009c00000000030180190000006003300210000000000223019f000000000300041400000ceb0430009c0000000001034019000000c001100210000000000121019f00000cf4011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d000000000101043b000d00000001001d000001000010043f00000cf801000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f00000001022001900000007e0000613d000000000101043b000000a00010043f000000400300043d00000060013000390000000d02000029000000000021043500000040013000390000000e020000290000000000210435000e00000003001d000000200230003900000cfa01000041000d00000002001d000000000012043500000cf801000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f00000001022001900000007e0000613d000000000101043b0000000e0300002900000080023000390000000000120435000000a0013000390000000002000410000c00000002001d0000000000210435000000a001000039000b00000001001d000000000013043500000cfb0130009c000000460000213d0000000e03000029000000c001300039000000400010043f00000ceb010000410000000d0400002900000ceb0240009c000000000201001900000000020440190000004002200210000000000303043300000ceb0430009c00000000030180190000006003300210000000000223019f000000000300041400000ceb0430009c0000000001034019000000c001100210000000000121019f00000cf4011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d000000000101043b000000800010043f0000000c01000029000000c00010043f00000009010000290000000001010433000e00000001001d00000cf60110009c000000460000213d0000000401000039000d00000001001d000000000101041a000000010210019000000001021002700000007f0320018f0000000002036019000c00000002001d0000001f0220008c00000000020000190000000102002039000000000121013f0000000101100190000004f60000c13d0000000c01000029000000200110008c000008b50000413d0000000d01000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d0000000e030000290000001f023000390000000502200270000000200330008c0000000002004019000000000301043b0000000c010000290000001f01100039000000050110027000000000011300190000000002230019000000000312004b000008b50000813d000000000002041b0000000102200039000000000312004b000008b10000413d0000000e010000290000001f0110008c000008e70000a13d0000000d01000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d00000011020000290000000e0300002900000000032301700000002002000039000000000101043b0000000906000029000008d50000613d0000002002000039000000000400001900000000056200190000000005050433000000000051041b000000200220003900000001011000390000002004400039000000000534004b000008cd0000413d0000000e04000029000000000343004b000008e30000813d0000000e030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f000000090400002900000000024200190000000002020433000000000232016f000000000021041b0000000e01000029000000010110021000000001011001bf000008f50000013d0000000e01000029000000000101004b0000000001000019000008ed0000613d000000060100002900000000010104330000000e040000290000000302400210000000010300008a000000000223022f000000000232013f000000000121016f0000000102400210000000000121019f0000000d02000029000000000012041b00000007010000290000000001010433000e00000001001d00000cf60110009c0000000801000029000000460000213d000000000101041a000000010210019000000001021002700000007f0320018f0000000002036019000d00000002001d0000001f0220008c00000000020000190000000102002039000000000121013f0000000101100190000004f60000c13d0000000d01000029000000200110008c000009290000413d0000000801000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d0000000e030000290000001f023000390000000502200270000000200330008c0000000002004019000000000301043b0000000d010000290000001f01100039000000050110027000000000011300190000000002230019000000000312004b000009290000813d000000000002041b0000000102200039000000000312004b000009250000413d0000000e010000290000001f0110008c0000095a0000a13d0000000801000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f00000001022001900000007e0000613d00000011020000290000000e0300002900000000032301700000002002000039000000000101043b0000000706000029000009490000613d0000002002000039000000000400001900000000056200190000000005050433000000000051041b000000200220003900000001011000390000002004400039000000000534004b000009410000413d0000000e04000029000000000343004b000009570000813d0000000e030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f000000070400002900000000024200190000000002020433000000000232016f000000000021041b0000000e010000290000000101100210000009680000013d0000000e01000029000000000101004b0000000001000019000009600000613d000000040100002900000000010104330000000e040000290000000302400210000000010300008a000000000223022f000000000232013f000000000121016f0000000102400210000500000002001d0000000502000029000000000121019f0000000802000029000000000012041b0000001901000039000000000201041a000001000300008a000000000232016f00000001022001bf000000000021041b000000100100002900000cee011001970000001002000039000000000302041a00000cf303300197000000000113019f000000000012041b0000000f0100002900000cee011001970000001102000039000000000302041a00000cf303300197000000000113019f000000000012041b000000800100043d000001400000044300000160001004430000002001000039000000a00200043d0000018000100443000001a0002004430000004002000039000000c00300043d000001c000200443000001e0003004430000006002000039000000e00300043d000002000020044300000220003004430000008002000039000001000300043d00000240002004430000026000300443000001200200043d0000000b030000290000028000300443000002a000200443000000c002000039000001400300043d000002c000200443000002e00030044300000100001004430000000701000039000001200010044300000cfc01000041000033a90001042e00000ceb0300004100000ceb0410009c0000000001038019000000400110021000000ceb0420009c00000000020380190000006002200210000000000112019f000000000200041400000ceb0420009c0000000002038019000000c002200210000000000112019f00000cf4011001c7000080100200003933a833a30000040f0000000102200190000009b40000613d000000000101043b000000000001042d0000000001000019000033aa00010430000000000301001900000ceb01000041000000000400041400000ceb0540009c0000000001044019000000c0011002100000006002200210000000000112001900000d7101100041000000000203001933a833a30000040f0000000102200190000009c50000613d000000000101043b000000000001042d0000000001000019000033aa0001043000000020030000390000000004310436000000000302043300000000003404350000004001100039000000000403004b000009d60000613d000000000400001900000000051400190000002004400039000000000624001900000000060604330000000000650435000000000534004b000009cf0000413d000000000213001900000000000204350000001f02300039000000200300008a000000000232016f0000000001120019000000000001042d00060000000000020000000001000416000000000101004b000009f60000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b000009f60000c13d00000002010003670000000402100370000000000302043b0000002401100370000000000501043b00000cee0150009c000009f80000a13d0000000001000019000033aa000104300000001904000039000000000104041a000000ff0210018f000000010220008c00000a2a0000c13d000001000200008a000300000002001d000000000121016f000400000004001d000000000014041b00000000003004350000000601000039000200000001001d000000200010043f00000ceb010000410000000002000414000600000003001d00000ceb0320009c0000000001024019000000c00110021000000d74011001c70000801002000039000500000005001d33a833a30000040f000000050400002900000006030000290000000102200190000009f60000613d000000000101043b000000000101041a00000cee0110019800000a3f0000c13d000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000000200041100000cee05200197000000000215004b00000a4e0000c13d0000000001030019000000000204001933a8304b0000040f0000000402000029000000000102041a0000000303000029000000000131016f00000001011001bf000000000012041b0000000001000019000033a90001042e000100000005001d00000000001004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000009f60000613d000000000101043b00000001020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000050400002900000006030000290000000102200190000009f60000613d000000000101043b000000000101041a000000ff0110019000000a430000c13d00000000003004350000000201000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000006030000290000000102200190000009f60000613d000000000101043b000000000101041a00000cee0110019800000a180000613d00000000003004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000050400002900000006030000290000000102200190000009f60000613d000000000101043b000000000101041a00000cee011001970000000102000029000000000121004b00000a430000613d000000400100043d000000440210003900000d7503000041000000000032043500000024021000390000001e03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa0001043000030000000000020000000001000416000000000101004b00000b290000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b00000b290000c13d00000002010003670000000402100370000000000202043b000300000002001d00000cee0220009c00000b290000213d0000002401100370000000000101043b000200000001001d00000000001004350000000601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000000b290000613d000000000101043b000000000101041a00000cee0210019800000ae70000c13d000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa000104300000000301000029000000000121004b00000aff0000c13d000000400100043d000000640210003900000d77030000410000000000320435000000440210003900000d7803000041000000000032043500000024021000390000002103000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000001010000390000000004000411000000000324004b00000b230000613d000100000004001d00000000002004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000000b290000613d000000000101043b000000010200002900000cee022001970000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000000b290000613d000000000101043b000000000101041a000000ff0110018f33a821730000040f0000000301000029000000020200002933a824d20000040f0000000001000019000033a90001042e0000000001000019000033aa0001043000000d790210009c00000b300000813d0000006001100039000000400010043f000000000001042d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa0001043000000d7a0210009c00000b3b0000813d0000004001100039000000400010043f000000000001042d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa0001043000000d7b0210009c00000b460000813d0000002001100039000000400010043f000000000001042d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa000104300000001f02200039000000200300008a000000000232016f0000000001120019000000000221004b0000000002000019000000010200403900000cf60310009c00000b590000213d000000010220019000000b590000c13d000000400010043f000000000001042d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000e0000000000020000000001000416000000000101004b00000bb00000c13d0000000001000031000000040210008a00000ced03000041000000400420008c0000000004000019000000000403401900000ced02200197000000000502004b000000000300a01900000ced0220009c00000000020400190000000002036019000000000202004b00000bb00000c13d00000002030003670000000402300370000000000202043b00000cf60420009c00000bb00000213d000000230420003900000ced05000041000000000614004b0000000006000019000000000605801900000ced0710019700000ced04400197000000000874004b0000000005008019000000000474013f00000ced0440009c00000000040600190000000004056019000000000404004b00000bb00000c13d0000000404200039000000000343034f000000000303043b00000cec0430009c00000cc80000813d00000005043002100000003f05400039000000200600008a000000000565016f000000400600043d0000000005560019000700000006001d000000000665004b0000000006000019000000010600403900000cf60750009c00000cc80000213d000000010660019000000cc80000c13d000000400050043f00000007050000290000000005350436000600000005001d00000024022000390000000004240019000000000114004b00000bb00000213d000000000103004b00000baa0000613d00000007010000290000000203200367000000000303043b000000200110003900000000003104350000002002200039000000000342004b00000ba30000413d00000024010000390000000201100367000000000101043b000300000001001d00000cee0110009c00000bb20000a13d0000000001000019000033aa000104300000001903000039000000000103041a000000ff0210018f000000010220008c00000bcf0000c13d000001000200008a000000000121016f000000000013041b0000000301000029000000000101004b00000be40000c13d000000400100043d000000440210003900000d8403000041000000000032043500000024021000390000001e03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000100000002001d000200000003001d00000007010000290000000002010433000000000102004b000d00000000001d000000000500001900000bff0000c13d0000001001000039000000000201041a000000400a00043d0000002401a00039000000000051043500000d800100004100000000001a04350000000401a0003900000003030000290000000000310435000000000100041400000cee02200197000000040320008c00000c700000c13d0000000103000031000000200130008c0000002004000039000000000403401900000ca30000013d0000001401000039000500000001001d0000801001000039000400000001001d000d00000000001d0000000001000019000c00000001001d000000010220008a00000007010000290000000001010433000000000121004b00000cfa0000a13d000a00000002001d0000000501200210000000060200002900000000011200190000000001010433000e00000001001d00000000001004350000000501000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000000040200002933a833a30000040f000000010220019000000bb00000613d000000400300043d00000d7c0230009c00000cc80000213d000000000101043b0000006002300039000000400020043f000000000201041a00000000042304360000000102100039000000000202041a000b00000004001d0000000000240435000900000003001d00000040023000390000000201100039000000000101041a000800000002001d00000000001204350000000e0100002900000000001004350000000601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000000bb00000613d000000000101043b000000000101041a00000cee0110019800000d000000613d0000000002000411000000000112004b00000d120000c13d0000000b010000290000000001010433000b00000001001d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f000000010220019000000bb00000613d000000000101043b0000000b02000029000000000121004b00000d240000413d000000090100002900000000010104330000000c020000290000000003120019000000000123004b00000000010000190000000101004039000000010110019000000cf40000c13d000000080100002900000000010104330000000d02000029000000000212001a000d00000002001d00000cf40000413d0000000e01000029000e00000003001d33a82a6a0000040f0000000e050000290000000a02000029000000000102004b000000000105001900000c050000c13d00000bec0000013d000e00000005001d00000ceb0300004100000ceb0410009c000000000103801900000ceb04a0009c00000000030a40190000004003300210000000c001100210000000000131019f00000d81011001c7000c0000000a001d33a8339e0000040f0000000c0a0000290000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f000000050640027200000c8f0000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b00000c870000413d000000000705004b00000c9e0000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000000e0500002900000cce0000613d0000001f01400039000000600210018f0000000001a20019000000000221004b0000000002000019000000010200403900000cf60410009c00000cc80000213d000000010220019000000cc80000c13d000000400010043f000000200230008c00000bb00000413d00000000020a0433000000000302004b0000000003000019000000010300c039000000000332004b00000bb00000c13d000000000202004b00000d390000c13d000000440210003900000d8303000041000000000032043500000d4d0200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa0001043000000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000000400200043d0000001f0430018f000000050330027200000cdb0000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b00000cd30000413d000000000504004b00000cea0000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa0001043000000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa0001043000000d550100004100000000001004350000003201000039000000040010043f00000d5601000041000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000440210003900000d7d03000041000000000032043500000024021000390000001c03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d7e030000410000000000320435000000440210003900000d7f03000041000000000032043500000024021000390000002503000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000020021000390000000d030000290000000000320435000000000051043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000112019f00000d74011001c70000800d02000039000000030300003900000d82040000410000000005000411000000030600002933a8339e0000040f000000010120019000000bb00000613d0000000202000029000000000102041a0000000103000029000000000131016f00000001011001bf000000000012041b0000000001000019000033a90001042e00090000000000020000000001000416000000000101004b00000d720000c13d000000040100008a000000000110003100000ced02000041000000600310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b00000d720000c13d00000002010003670000002402100370000000000702043b0000000402100370000000000602043b0000004401100370000000000501043b00000cee0150009c00000d740000a13d0000000001000019000033aa000104300000001903000039000000000103041a000000ff0210018f000000010220008c00000d910000c13d000001000200008a000400000002001d000000000121016f000500000003001d000000000013041b0000001001000039000000000201041a000000400b00043d00000d850100004100000000001b04350000000001000411000600000001001d00000cee091001970000000401b000390000000000910435000000000100041400000cee08200197000000040280008c00000da60000c13d0000000103000031000000200130008c0000002004000039000000000403401900000de20000013d000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000200000009001d000900000007001d000800000006001d000700000005001d00000ceb0200004100000ceb0310009c000000000102801900000ceb03b0009c00000000020b40190000004002200210000000c001100210000000000121019f00000d56011001c7000300000008001d000000000208001900010000000b001d33a833a30000040f000000010b0000290000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f000000050640027200000dca0000613d0000000007000019000000050870021000000000098b0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b00000dc20000413d000000000705004b00000dd90000613d0000000506600210000000000761034f00000000066b00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000000705000029000000080600002900000009070000290000000308000029000000020900002900000e060000613d0000001f01400039000000600110018f000000000ab1001900000000011a004b0000000001000019000000010100403900000cf602a0009c00000e7b0000213d000000010110019000000e7b0000c13d0000004000a0043f000000200130008c00000d720000413d00000000010b0433000000000161004b00000e2c0000813d0000006401a0003900000d930200004100000000002104350000004401a0003900000d940200004100000000002104350000002401a000390000002102000039000000000021043500000d4d0100004100000000001a04350000000401a000390000002002000039000000000021043500000ceb0100004100000ceb02a0009c00000000010a4019000000400110021000000d54011001c7000033aa00010430000000400200043d0000001f0430018f000000050330027200000e130000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b00000e0b0000413d000000000504004b00000e220000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa000104300000004401a000390000000000610435000000000100041000000cee011001970000002402a00039000000000012043500000d860100004100000000001a04350000000401a0003900000000009104350000000001000414000000040280008c00000e3e0000c13d0000000103000031000000200130008c0000002004000039000000000403401900000e760000013d000900000007001d000800000006001d000700000005001d00000ceb0200004100000ceb0310009c000000000102801900000ceb03a0009c00000000020a40190000004002200210000000c001100210000000000121019f00000d4e011001c7000000000208001900030000000a001d33a8339e0000040f000000030a0000290000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f000000050640027200000e600000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b00000e580000413d000000000705004b00000e6f0000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f0003000000010355000000010220019000000007050000290000000806000029000000090700002900000e9c0000613d0000001f01400039000000600110018f0000000001a1001900000cf60210009c00000e810000a13d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000000400010043f000000200230008c00000d720000413d00000000020a0433000000000302004b0000000003000019000000010300c039000000000332004b00000d720000c13d000000000202004b00000ec20000c13d000000440210003900000d9203000041000000000032043500000d4d0200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400200043d0000001f0430018f000000050330027200000ea90000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b00000ea10000413d000000000504004b00000eb80000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa0001043000000d870270009c00000ed80000213d000000640210003900000d90030000410000000000320435000000440210003900000d9103000041000000000032043500000024021000390000002303000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000d880270009c00000eee0000413d000000640210003900000d8e030000410000000000320435000000440210003900000d8f03000041000000000032043500000024021000390000002203000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000900000007001d000700000005001d000800000006001d000000000206004b00000f070000c13d000000640210003900000d8c030000410000000000320435000000440210003900000d8d03000041000000000032043500000024021000390000002703000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300000000804000029000000090500002900000000324500a900000000434200d9000000000353004b00000f220000c13d00000d513420012a000300000004001d00000d890220009c00000ef30000a13d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000000090200002900000d720000613d000000000101043b000000000421001a00000f220000413d00000f280000013d00000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa0001043000000007010000290000000802000029000000030300002933a8275a0000040f000000400100043d0000004002100039000000090300002900000000003204350000002002100039000000030300002900000000003204350000000802000029000000000021043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000112019f00000d8a011001c70000800d02000039000000030300003900000d8b040000410000000605000029000000070600002933a8339e0000040f000000010120019000000d720000613d0000000502000029000000000102041a0000000403000029000000000131016f00000001011001bf000000000012041b0000000001000019000033a90001042e000000040110008a00000ced020000410000005f0310008c0000000003000019000000000302201900000ced01100197000000000401004b000000000200801900000ced0110009c00000000010300190000000001026019000000000101004b00000f680000613d00000002030003670000000401300370000000000101043b00000cee0210009c00000f680000213d0000002402300370000000000202043b00000cee0420009c00000f680000213d0000004403300370000000000303043b000000000001042d0000000001000019000033aa00010430000b0000000000020000000001000416000000000101004b00000f8b0000c13d000000040100008a000000000110003100000ced02000041000000e00310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b00000f8b0000c13d00000002010003670000000402100370000000000802043b0000002402100370000000000902043b00000cee0290009c00000f8b0000213d0000006402100370000000000b02043b0000004402100370000000000d02043b0000008402100370000000000e02043b000000ff02e0008c00000f8d0000a13d0000000001000019000033aa00010430000000c401100370000000000f01043b000000190a00003900000000010a041a000000ff0210018f000000010220008c00000fae0000c13d000001000c00008a0000000001c1016f00000000001a041b000000400100043d00000d9502f0009c00000fc30000413d000000640210003900000d9a030000410000000000320435000000440210003900000d9b03000041000000000032043500000024021000390000002503000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300000000404000039000000000504041a000000010650019000000001025002700000007f0320018f000000000302c0190000001f0230008c00000000020000190000000102002039000000010220018f000000000226004b00000fd50000613d00000d550100004100000000001004350000002201000039000000040010043f00000d5601000041000033aa000104300000000002310436000000000606004b00000fe60000613d0000000000400435000000000403004b000000000400001900000feb0000613d00000d6a0500004100000000040000190000000006420019000000000705041a000000000076043500000001055000390000002004400039000000000634004b00000fde0000413d00000feb0000013d0000000004c5016f0000000000420435000000000303004b000000200400003900000000040060190000003f03400039000000200400008a000000000443016f0000000003140019000000000443004b0000000004000019000000010400403900000cf60530009c000010160000213d0000000104400190000010160000c13d00060000000f001d00040000000c001d00050000000a001d000000400030043f00000ceb0300004100000ceb0420009c00000000020380190000004002200210000000000101043300000ceb0410009c00000000010380190000006001100210000000000121019f000000000200041400000ceb0420009c0000000002038019000000c002200210000000000112019f00000cf4011001c70000801002000039000b00000008001d000a00000009001d00090000000b001d00080000000d001d00070000000e001d33a833a30000040f000000010220019000000f8b0000613d000000000301043b000000400100043d00000cef0210009c0000101c0000a13d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000300000003001d0000004002100039000000400020043f0000000102000039000000000121043600000cf202000041000000000021043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000121019f00000d96011001c7000080100200003933a833a30000040f000000010220019000000f8b0000613d000000000101043b000100000001001d000000400100043d000200000001001d00000cf801000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f000000010220019000000f8b0000613d00000002050000290000002002500039000000000101043b00000d69030000410000000000320435000000000300041000000cee03300197000000a004500039000000000034043500000080035000390000000000130435000000600150003900000001030000290000000000310435000000400150003900000003030000290000000000310435000000a003000039000000000035043500000cfb0150009c000010160000213d000300000003001d000000c001500039000000400010043f00000ceb0100004100000ceb0320009c00000000020180190000004002200210000000000305043300000ceb0430009c00000000030180190000006003300210000000000223019f000000000300041400000ceb0430009c0000000001034019000000c001100210000000000121019f00000cf4011001c7000080100200003933a833a30000040f000000080600002900000009050000290000000a030000290000000b04000029000000010220019000000f8b0000613d000000000101043b000200000001001d000000400100043d000000a00210003900000000005204350000008002100039000000000062043500000cee023001970000006003100039000000000023043500000040021000390000000000420435000000200210003900000d500300004100000000003204350000000303000029000000000031043500000cfb0310009c000010160000213d000000c003100039000000400030043f00000ceb0300004100000ceb0420009c00000000020380190000004002200210000000000101043300000ceb0410009c00000000010380190000006001100210000000000121019f000000000200041400000ceb0420009c0000000002038019000000c002200210000000000112019f00000cf4011001c7000080100200003933a833a30000040f000000010220019000000f8b0000613d000000000201043b000000400100043d00000042031000390000000000230435000000200210003900000d970300004100000000003204350000002203100039000000020400002900000000004304350000004203000039000000000031043500000d980310009c000010160000213d0000008003100039000000400030043f00000ceb0300004100000ceb0420009c00000000020380190000004002200210000000000101043300000ceb0410009c00000000010380190000006001100210000000000121019f000000000200041400000ceb0420009c0000000002038019000000c002200210000000000112019f00000cf4011001c7000080100200003933a833a30000040f0000000705000029000000010220019000000f8b0000613d000000000101043b000000a4020000390000000202200367000000000202043b000000400300043d00000060043000390000000606000029000000000064043500000040043000390000000000240435000000ff0250018f000000200430003900000000002404350000000000130435000000000000043500000ceb01000041000000000200041400000ceb0420009c000000000201801900000ceb0430009c00000000010340190000004001100210000000c002200210000000000112019f00000d99011001c7000000010200003933a833a30000040f0000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000504400272000010e80000613d00000000060000190000000507600210000000000871034f000000000808043b00000000008704350000000106600039000000000746004b000010e10000413d000000000605004b000010f60000613d00000003055002100000000504400210000000000604043300000000065601cf000000000656022f000000000741034f000000000707043b0000010005500089000000000757022f00000000055701cf000000000565019f0000000000540435000100000003001f00030000000103550000000102200190000011200000613d0000000001000433000700000001001d0000000b0200002933a822900000040f33a82fee0000040f000000070100002900000cee011001980000000001000019000000010100c03933a830060000040f000000070100002933a832d80000040f0000000802000029000000000112004b0000000001000019000000010100603933a8301e0000040f00000d5c0100004100000000001004390000800b01000039000000040200003933a809b60000040f0000000902000029000000000121004b0000000001000019000000010100a03933a830360000040f0000000b010000290000000a0200002933a8304b0000040f0000000502000029000000000102041a0000000403000029000000000131016f00000001011001bf000000000012041b0000000001000019000033a90001042e000000400200043d0000001f0430018f00000005033002720000112d0000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000011250000413d000000000504004b0000113c0000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa0001043000020000000000020000000001000416000000000101004b000011860000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b000011860000c13d00000002010003670000000402100370000000000302043b00000cee0230009c000011860000213d0000002401100370000000000101043b000100000001001d00000d5c01000041000000000010043900000ceb010000410000000002000414000200000003001d00000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f00000002030000290000000102200190000011860000613d000000000101043b00000d5e0210009c000011880000413d000000400100043d000000640210003900000d61030000410000000000320435000000440210003900000d6203000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300000000001000019000033aa000104300000000102000029000000000112004b000011a00000813d00000000003004350000001601000039000000200010043f0000004002000039000000000100001933a809a00000040f000200000001001d000000010100002933a82fd60000040f0000000002010019000000020100002933a82f060000040f00000d5801100197000000400200043d000000000012043500000ceb0100004100000ceb0320009c0000000001024019000000400110021000000d4b011001c7000033a90001042e000000400100043d000000640210003900000d9c030000410000000000320435000000440210003900000d9d03000041000000000032043500000024021000390000002203000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000080000000000020000000001000416000000000101004b000011c70000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b000011c90000613d0000000001000019000033aa0001043000000002010003670000002402100370000000000402043b0000000401100370000000000501043b0000001903000039000000000103041a000000ff0210018f000000010220008c000011ec0000c13d000700000004001d000001000200008a000400000002001d000000000121016f000500000003001d000000000013041b0000001001000039000000000201041a000000400b00043d00000d850100004100000000001b04350000000001000411000600000001001d00000cee071001970000000401b000390000000000710435000000000100041400000cee06200197000000040260008c000012010000c13d0000000103000031000000200130008c00000020040000390000000004034019000012390000013d000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000200000007001d000800000005001d00000ceb0200004100000ceb0310009c000000000102801900000ceb03b0009c00000000020b40190000004002200210000000c001100210000000000121019f00000d56011001c7000300000006001d000000000206001900010000000b001d33a833a30000040f000000010b0000290000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000506400272000012230000613d0000000007000019000000050870021000000000098b0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b0000121b0000413d000000000705004b000012320000613d0000000506600210000000000761034f00000000066b00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000000805000029000000030600002900000002070000290000125d0000613d0000001f01400039000000600110018f000000000ab1001900000000011a004b0000000001000019000000010100403900000cf602a0009c000012ce0000213d0000000101100190000012ce0000c13d0000004000a0043f000000200130008c000011c70000413d00000000010b0433000000000151004b000012830000813d0000006401a0003900000d930200004100000000002104350000004401a0003900000d940200004100000000002104350000002401a000390000002102000039000000000021043500000d4d0100004100000000001a04350000000401a000390000002002000039000000000021043500000ceb0100004100000ceb02a0009c00000000010a4019000000400110021000000d54011001c7000033aa00010430000000400200043d0000001f0430018f00000005033002720000126a0000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000012620000413d000000000504004b000012790000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa000104300000004401a000390000000000510435000000000100041000000cee011001970000002402a00039000000000012043500000d860100004100000000001a04350000000401a0003900000000007104350000000001000414000000040260008c000012950000c13d0000000103000031000000200130008c00000020040000390000000004034019000012c90000013d000800000005001d00000ceb0200004100000ceb0310009c000000000102801900000ceb03a0009c00000000020a40190000004002200210000000c001100210000000000121019f00000d4e011001c7000000000206001900030000000a001d33a8339e0000040f000000030a0000290000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000506400272000012b50000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000012ad0000413d000000000705004b000012c40000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000000805000029000012ef0000613d0000001f01400039000000600110018f0000000001a1001900000cf60210009c000012d40000a13d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000000400010043f000000200230008c000011c70000413d00000000020a0433000000000302004b0000000003000019000000010300c039000000000332004b000011c70000c13d000000000202004b000013150000c13d000000440210003900000d9203000041000000000032043500000d4d0200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400200043d0000001f0430018f0000000503300272000012fc0000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000012f40000413d000000000504004b0000130b0000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa00010430000000070400002900000d870240009c0000132c0000213d000000640210003900000d90030000410000000000320435000000440210003900000d9103000041000000000032043500000024021000390000002303000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000d880240009c000013420000413d000000640210003900000d8e030000410000000000320435000000440210003900000d8f03000041000000000032043500000024021000390000002203000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000000205004b000013580000c13d000000640210003900000d8c030000410000000000320435000000440210003900000d8d03000041000000000032043500000024021000390000002703000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000000325400a9000800000005001d000000000604001900000000435200d9000000000363004b000013730000c13d00000d513420012a000300000004001d00000d890220009c000013440000a13d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000011c70000613d000000000101043b0000000702000029000000000421001a000013730000413d000013790000013d00000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa0001043000000006010000290000000802000029000000030300002933a8275a0000040f000000400100043d0000004002100039000000070300002900000000003204350000002002100039000000030300002900000000003204350000000802000029000000000021043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000112019f00000d8a011001c70000800d02000039000000030300003900000d8b040000410000000605000029000000000605001933a8339e0000040f0000000101200190000011c70000613d0000000502000029000000000102041a0000000403000029000000000131016f00000001011001bf000000000012041b0000000001000019000033a90001042e00020000000000020000000001000416000000000101004b000013e40000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b000013e40000c13d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000013e40000613d000000000101043b000200000001001d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000013e40000613d000000000301043b00000d5e0230009c000013e60000413d000000400100043d000000640210003900000d61030000410000000000320435000000440210003900000d6203000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300000000001000019000033aa00010430000000400100043d0000000202000029000000000223004b000014010000c13d000100000001001d33a80b360000040f0000000103000029000000200130003900000d9f0200004100000000002104350000001b0100003900000000001304350000000002030019000000400100043d000200000001001d33a809c70000040f0000000204000029000000000141004900000ceb0200004100000ceb0310009c000000000102801900000ceb0340009c000000000204401900000040022002100000006001100210000000000121019f000033a90001042e000000440310003900000d9e02000041000000000023043500000024031000390000001d02000039000000000023043500000d4d02000041000000000021043500000004031000390000002002000039000000000023043500000ceb0300004100000ceb0210009c0000000001038019000000400110021000000d4e011001c7000033aa0001043000070000000000020000000001000416000000000101004b000014af0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b000014af0000c13d00000004010000390000000201100367000000000101043b000500000001001d00000cee0110009c000014af0000213d0000000502000029000000000102004b000014420000c13d000000400100043d000000640210003900000da2030000410000000000320435000000440210003900000da303000041000000000032043500000024021000390000002903000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000000002004350000000701000039000300000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000014af0000613d000000000101043b000000000101041a000200000001001d000000000101004b00000000020000190000145e0000c13d000000400100043d000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4b011001c7000033a90001042e0000801001000039000600000001001d0000000a01000039000100000001001d0000000002000019000700000000001d000400000002001d000000050100002900000000001004350000000301000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000000060200002933a833a30000040f0000000102200190000014af0000613d000000000101043b000000000101041a0000000702000029000000000121004b000014b10000a13d000000050100002900000000001004350000000101000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000000060200002933a833a30000040f0000000102200190000014af0000613d000000000101043b00000007020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000000060200002933a833a30000040f0000000102200190000014af0000613d000000000101043b000000000101041a00000000001004350000001401000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000014af0000613d000000000101043b000000000101041a0000000402000029000000000212001a000014c60000413d000000070300002900000001033000390000000201000029000700000003001d000000000113004b000014640000413d000014560000013d0000000001000019000033aa00010430000000400100043d000000640210003900000da0030000410000000000320435000000440210003900000da103000041000000000032043500000024021000390000002b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa0001043000090000000000020000000001000416000000000101004b000016890000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b000016890000c13d00000002010003670000002402100370000000000502043b0000000401100370000000000401043b0000001903000039000000000103041a000000ff0210018f000000010220008c000015250000c13d000700000005001d000001000200008a000500000002001d000000000121016f000600000003001d000000000013041b000900000004001d00000000004004350000000601000039000800000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000016890000613d000000000101043b000000000101041a00000cee01100198000015130000613d000000090100002900000000001004350000000801000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000016890000613d000000000101043b000000000101041a00000cee011001980000153a0000c13d000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300000000002000411000400000002001d00000cee03200197000000000213004b000015560000c13d000000090100002900000000001004350000001401000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000016890000613d000000400300043d00000d790230009c000015b10000413d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000300000003001d00000000001004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000016890000613d000000000101043b00000003020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000016890000613d000000000101043b000000000101041a000000ff011001900000153f0000c13d000000090100002900000000001004350000000801000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000016890000613d000000000101043b000000000101041a00000cee01100198000015130000613d000000090100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000016890000613d000000000101043b000000000101041a00000cee011001970000000302000029000000000121004b0000153f0000613d000000400100043d000000640210003900000da4030000410000000000320435000000440210003900000da503000041000000000032043500000024021000390000002b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000000101043b0000006002300039000000400020043f000000000201041a00000000042304360000000102100039000000000202041a000800000004001d0000000000240435000300000003001d00000040023000390000000201100039000000000101041a000200000002001d000000000012043500000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000016890000613d000000000101043b00000007030000290000000004310019000000000114004b000000000100001900000001010040390000000101100190000015da0000613d00000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa0001043000000008010000290000000001010433000000000114004b000015f30000813d000000400100043d000000640210003900000daa030000410000000000320435000000440210003900000da803000041000000000032043500000024021000390000002f03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300000000301000029000000000101043300000d870230009c0000160c0000213d000000400100043d000000640210003900000d90030000410000000000320435000000440210003900000d9103000041000000000032043500000024021000390000002303000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000100000004001d00000d880230009c000016240000413d000000400100043d000000640210003900000d8e030000410000000000320435000000440210003900000d8f03000041000000000032043500000024021000390000002203000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000000201004b0000163b0000c13d000000400100043d000000640210003900000da9030000410000000000320435000000440210003900000da803000041000000000032043500000024021000390000003303000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000070400002900000000324100a900000000311200d9000000000141004b000015d40000c13d00000d511320012a000700000003001d00000d890120009c000016260000a13d000000020100002900000000010104330000000702000029000000000112004b0000165e0000813d000000400100043d000000640210003900000da7030000410000000000320435000000440210003900000da803000041000000000032043500000024021000390000003103000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000090100002933a82a6a0000040f0000000301000029000000000201043300000004010000290000000703000029000000010400002933a8275a0000040f00000008010000290000000001010433000000400200043d000000400320003900000001040000290000000000430435000000200320003900000000001304350000000901000029000000000012043500000ceb01000041000000000300041400000ceb0430009c000000000301801900000ceb0420009c00000000010240190000004001100210000000c002300210000000000112019f00000d8a011001c70000800d02000039000000020300003900000da604000041000000040500002933a8339e0000040f0000000101200190000016890000613d0000000602000029000000000102041a0000000503000029000000000131016f00000001011001bf000000000012041b0000000001000019000033a90001042e0000000001000019000033aa00010430000b0000000000020000000001000416000000000101004b0000169d0000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000169f0000613d0000000001000019000033aa0001043000000002010003670000002402100370000000000502043b0000000401100370000000000401043b0000001903000039000000000103041a000000ff0210018f000000010220008c000016e70000c13d000b00000005001d000001000200008a000700000002001d000000000121016f000800000003001d000000000013041b000900000004001d00000000004004350000000601000039000a00000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a00000cee01100198000016d50000613d000600000001001d0000000b0100002900000000001004350000000a01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a00000cee03100198000016fc0000c13d000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000009020000290000000b01000029000000000112004b000017120000c13d000000400100043d000000440210003900000dae03000041000000000032043500000024021000390000001a03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000500000003001d00000000002004350000000a01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a00000cee01100198000016d50000613d0000000002000411000300000002001d00000cee02200197000400000002001d000000000212004b000017580000c13d0000000b0100002900000000001004350000000a01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a00000cee01100198000016d50000613d0000000402000029000000000212004b000017ae0000c13d000000090100002900000000001004350000001401000039000a00000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000400200043d000400000002001d00000d790220009c000017f40000413d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa0001043000000000001004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b00000004020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a000000ff011001900000172a0000c13d000000090100002900000000001004350000000a01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a00000cee01100198000016d50000613d000000090100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a00000cee011001970000000402000029000000000121004b0000172a0000613d000000400100043d000000440210003900000dab03000041000000000032043500000d4d0200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa0001043000000000001004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b00000004020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a000000ff011001900000173f0000c13d0000000b0100002900000000001004350000000a01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a00000cee01100198000016d50000613d0000000b0100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000000101043b000000000101041a00000cee011001970000000402000029000000000121004b0000179d0000c13d0000173f0000013d000000000101043b00000004030000290000006002300039000000400020043f000000000201041a00000000042304360000000102100039000000000202041a000200000004001d000000000024043500000040023000390000000201100039000000000101041a000100000002001d00000000001204350000000b0100002900000000001004350000000a01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000169d0000613d000000400200043d00000d7c0320009c000017520000213d000000000101043b0000006003200039000000400030043f000000000301041a00000000033204360000000104100039000000000404041a00000000004304350000000201100039000000000101041a00000040042000390000000000140435000000000303043300000002040000290000000004040433000000000534004b0000000003042019000a00000003001d0000000002020433000000040300002900000000030304330000000003320019000400000003001d000000000223004b000000000200001900000001020040390000000102200190000018360000c13d00000001020000290000000002020433000000000112001a000200000001001d000018360000413d0000183c0000013d00000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa00010430000000090100002933a82a6a0000040f0000000b0100002933a82a6a0000040f0000000f01000039000000000101041a000100000001001d0000000301000029000000040200002900000002030000290000000a0400002933a8275a0000040f000000400100043d00000040021000390000000b0300002900000000003204350000002002100039000000090300002900000000003204350000000502000029000000000021043500000060021000390000000103000029000000000032043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000112019f00000dac011001c70000800d02000039000000030300003900000dad040000410000000305000029000000060600002933a8339e0000040f00000001012001900000169d0000613d0000000802000029000000000102041a0000000703000029000000000131016f00000001011001bf000000000012041b000000400100043d0000000102000029000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4b011001c7000033a90001042e00090000000000020000000001000416000000000101004b000018920000c13d000000040100008a000000000110003100000ced02000041000000800310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b000018920000c13d00000002010003670000004402100370000000000402043b0000002402100370000000000302043b0000000402100370000000000702043b0000006401100370000000000501043b00000cee0150009c000018940000a13d0000000001000019000033aa000104300000001906000039000000000106041a000000ff0210018f000000010220008c000018b40000c13d000001000200008a000000000121016f000000000016041b0000001301000039000000000101041a00000cee081001970000000001000411000000000181004b000018c90000c13d000300000002001d000400000006001d0000001001000039000000000201041a000000400d00043d00000d850100004100000000001d04350000000401d000390000000000810435000000000100041400000cee06200197000000040260008c000018db0000c13d000000010a0000310000002001a0008c000000200b000039000000000b0a4019000019190000013d000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000440210003900000daf03000041000000000032043500000024021000390000001b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000500000008001d000600000007001d000700000004001d000800000003001d000900000005001d00000ceb0200004100000ceb0310009c000000000102801900000ceb03d0009c00000000020d40190000004002200210000000c001100210000000000121019f00000d56011001c7000200000006001d000000000206001900010000000d001d33a833a30000040f000000010d0000290000000003010019000000600330027000000ceb0a3001970000002004a0008c000000200b000039000000000b0a40190000001f05b0018f0000000506b00272000019000000613d0000000007000019000000050870021000000000098d0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000018f80000413d000000000705004b0000190f0000613d0000000506600210000000000761034f00000000066d00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f000000000056043500010000000a001f000300000001035500000001022001900000000905000029000000080300002900000007040000290000000607000029000000050800002900000002060000290000193d0000613d0000001f01b00039000000600110018f000000000cd1001900000000011c004b0000000001000019000000010100403900000cf602c0009c000019b60000213d0000000101100190000019b60000c13d0000004000c0043f0000002001a0008c000018920000413d00000000010d0433000000000171004b000019630000813d0000006401c0003900000db20200004100000000002104350000004401c0003900000db30200004100000000002104350000002401c000390000002802000039000000000021043500000d4d0100004100000000001c04350000000401c000390000002002000039000000000021043500000ceb0100004100000ceb02c0009c00000000010c4019000000400110021000000d54011001c7000033aa00010430000000400200043d0000001f04a0018f0000000503a002720000194a0000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000019420000413d000000000504004b000019590000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa000104300000004401c000390000000000710435000000000100041000000cee011001970000002402c00039000000000012043500000d860100004100000000001c04350000000401c0003900000000008104350000000001000414000000040260008c000019750000c13d000000010a0000310000002001a0008c000000200b000039000000000b0a4019000019b10000013d000500000008001d000600000007001d000700000004001d000800000003001d000900000005001d00000ceb0200004100000ceb0310009c000000000102801900000ceb03c0009c00000000020c40190000004002200210000000c001100210000000000121019f00000d4e011001c7000000000206001900020000000c001d33a8339e0000040f000000020c0000290000000003010019000000600330027000000ceb0a3001970000002004a0008c000000200b000039000000000b0a40190000001f05b0018f0000000506b00272000019990000613d0000000007000019000000050870021000000000098c0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000019910000413d000000000705004b000019a80000613d0000000506600210000000000761034f00000000066c00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f000000000056043500010000000a001f0003000000010355000000010220019000000009050000290000000803000029000000070400002900000006070000290000000508000029000019db0000613d0000001f01b00039000000600110018f0000000001c1001900000cf60210009c000019bc0000a13d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000000400010043f0000002002a0008c000018920000413d00000000020c0433000000000602004b0000000006000019000000010600c039000000000662004b000018920000c13d000000000202004b00001a010000c13d000000640210003900000db0030000410000000000320435000000440210003900000db103000041000000000032043500000024021000390000002703000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400200043d0000001f04a0018f0000000503a00272000019e80000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000019e00000413d000000000504004b000019f70000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa0001043000000000010500190000000002070019000900000005001d000800000003001d000700000004001d000600000007001d000500000008001d33a8275a0000040f000000400100043d0000004002100039000000070300002900000000003204350000002002100039000000080300002900000000003204350000000602000029000000000021043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000112019f00000d8a011001c70000800d02000039000000030300003900000d8b040000410000000505000029000000090600002933a8339e0000040f0000000101200190000018920000613d0000000402000029000000000102041a0000000303000029000000000131016f00000001011001bf000000000012041b0000000001000019000033a90001042e00060000000000020000000001000416000000000101004b00001b680000c13d000000040100008a000000000110003100000ced02000041000000000301004b0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b00001b680000c13d00000db40100004100000000001004390000000001000412000600000001001d0000000400100443000000a001000039000000240010044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000db5011001c7000080050200003933a833a30000040f000000010220019000001b680000613d000000000101043b000000ff0210008c00001a640000c13d0000000204000039000000000304041a000000010530019000000001013002700000007f0210018f00000000010260190000001f0210008c00000000020000190000000102002039000000010220018f000000000225004b00001a700000613d00000d550100004100000000001004350000002201000039000000040010043f00000d5601000041000033aa00010430000000400400043d000000ff0210018f000000200320008c00001a820000413d00000db601000041000000000014043500000ceb0100004100000ceb0240009c0000000001044019000000400110021000000db7011001c7000033aa00010430000000400700043d0000000002170436000000000505004b00001a8b0000613d0000000000400435000000000301004b000000000300001900001a910000613d00000db80400004100000000030000190000000005320019000000000604041a000000000065043500000001044000390000002003300039000000000513004b00001a7a0000413d00001a910000013d00000cef0340009c00001afa0000213d0000004003400039000000400030043f00000020034000390000000000130435000500000004001d000000000024043500001a9e0000013d000001000400008a000000000343016f0000000000320435000000000101004b000000200300003900000000030060190000003f01300039000000200200008a000000000221016f0000000001720019000000000221004b0000000002000019000000010200403900000cf60310009c00001afa0000213d000000010220019000001afa0000c13d000500000007001d000000400010043f00000db401000041000000000010043900000006010000290000000400100443000000c001000039000000240010044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000db5011001c7000080050200003933a833a30000040f000000010220019000001b680000613d000000000201043b000000ff0120008c00001acf0000c13d0000000305000039000000000405041a000000010640019000000001014002700000007f0210018f000000000201c0190000001f0120008c00000000010000190000000101002039000000000114013f000000010110019000001a5e0000c13d000000400100043d0000000003210436000000000606004b00001ae50000613d0000000000500435000000000402004b000000000400001900001aeb0000613d00000db90500004100000000040000190000000006430019000000000705041a000000000076043500000001055000390000002004400039000000000624004b00001ac70000413d00001aeb0000013d000000400100043d000000ff0320018f000000200430008c00001adb0000413d00000db602000041000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000db7011001c7000033aa0001043000000cef0410009c000000050700002900001afa0000213d0000004004100039000000400040043f000000200410003900000000002404350000000000310435000000400400043d00001af80000013d000001000500008a000000000454016f0000000000430435000000000202004b000000200400003900000000040060190000003f02400039000000200300008a000000000232016f0000000004120019000000000224004b0000000002000019000000010200403900000cf60340009c000000050700002900001afa0000213d000000010220019000001afa0000c13d000000400040043f00000dba0240009c00001b000000a13d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa000104300000002002400039000400000002001d000000400020043f000500000004001d0000000000040435000000400800043d0000002002800039000000e003000039000000000032043500000dbb0200004100000000002804350000000002070433000000e00380003900000000002304350000010003800039000000000402004b00001b190000613d000000000400001900000000053400190000002004400039000000000674001900000000060604330000000000650435000000000524004b00001b120000413d000000000432001900000000000404350000001f02200039000000200400008a000300000004001d000000000242016f00000000023200190000000003820049000600000008001d0000004004800039000000000034043500000000060104330000000005620436000000000206004b00001b300000613d000000000200001900000000035200190000002002200039000000000412001900000000040404330000000000430435000000000362004b00001b290000413d0000000001560019000000000001043500000cf801000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b02000039000200000005001d000100000006001d33a833a30000040f000000010220019000001b680000613d000000000101043b00000006050000290000008002500039000000000300041000000000003204350000006002500039000000000012043500000001010000290000001f011000390000000302000029000000000121016f000000020200002900000000012100190000000002510049000000c0035000390000000000230435000000a0025000390000000000020435000000050200002900000000020204330000000001210436000000000302004b000000040600002900001b5e0000613d0000000003000019000000006406043400000000014104360000000103300039000000000423004b00001b590000413d000000000151004900000ceb0200004100000ceb0310009c000000000102801900000ceb0350009c000000000205401900000040022002100000006001100210000000000121019f000033a90001042e0000000001000019000033aa00010430000e0000000000020000000001000416000000000101004b00001bab0000c13d0000000001000031000000040210008a00000ced03000041000000200420008c0000000004000019000000000403401900000ced02200197000000000502004b000000000300a01900000ced0220009c00000000020400190000000002036019000000000202004b00001bab0000c13d00000002030003670000000402300370000000000202043b00000cf60420009c00001bab0000213d000000230420003900000ced05000041000000000614004b0000000006000019000000000605801900000ced0710019700000ced04400197000000000874004b0000000005008019000000000474013f00000ced0440009c00000000040600190000000004056019000000000404004b00001bab0000c13d0000000404200039000000000343034f000000000303043b00000cec0430009c00001ccf0000813d00000005043002100000003f05400039000000200600008a000000000565016f000000400600043d0000000005560019000700000006001d000000000665004b0000000006000019000000010600403900000cf60750009c00001ccf0000213d000000010660019000001ccf0000c13d000000400050043f00000007050000290000000005350436000600000005001d00000024022000390000000004240019000000000114004b00001bad0000a13d0000000001000019000033aa00010430000000000103004b00001bb70000613d00000007010000290000000203200367000000000303043b000000200110003900000000003104350000002002200039000000000342004b00001bb00000413d0000001903000039000000000103041a000000ff0210018f000000010220008c00001bd60000c13d000001000200008a000200000002001d000000000121016f000000000013041b0000000001000411000500000001001d000000000101004b00001beb0000c13d000000400100043d000000440210003900000d8403000041000000000032043500000024021000390000001e03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000007010000290000000002010433000000000102004b000d00000000001d0000000005000019000100000003001d00001c060000c13d0000001001000039000000000201041a000000400a00043d0000002401a00039000000000051043500000d800100004100000000001a0435000000050100002900000cee011001970000000403a000390000000000130435000000000100041400000cee02200197000000040320008c00001c770000c13d0000000103000031000000200130008c0000002004000039000000000403401900001caa0000013d0000001401000039000400000001001d0000801001000039000300000001001d000d00000000001d0000000003000019000000010220008a00000007010000290000000001010433000000000121004b00001d010000a13d000c00000003001d000a00000002001d0000000501200210000000060200002900000000011200190000000001010433000e00000001001d00000000001004350000000401000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000000030200002933a833a30000040f000000010220019000001bab0000613d000000400300043d00000d7c0230009c00001ccf0000213d000000000101043b0000006002300039000000400020043f000000000201041a00000000042304360000000102100039000000000202041a000b00000004001d0000000000240435000900000003001d00000040023000390000000201100039000000000101041a000800000002001d00000000001204350000000e0100002900000000001004350000000601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000001bab0000613d000000000101043b000000000101041a00000cee0110019800001d070000613d0000000502000029000000000112004b00001d190000c13d0000000b010000290000000001010433000b00000001001d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f000000010220019000001bab0000613d000000000101043b0000000b02000029000000000121004b00001d2b0000413d000000090100002900000000010104330000000c020000290000000003120019000000000123004b00000000010000190000000101004039000000010110019000001cfb0000c13d000000080100002900000000010104330000000d02000029000000000212001a000d00000002001d00001cfb0000413d0000000e01000029000e00000003001d33a82a6a0000040f0000000e050000290000000a02000029000000000102004b000000000305001900001c0c0000c13d00001bf20000013d000e00000005001d00000ceb0300004100000ceb0410009c000000000103801900000ceb04a0009c00000000030a40190000004003300210000000c001100210000000000131019f00000d81011001c7000c0000000a001d33a8339e0000040f0000000c0a0000290000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f000000050640027200001c960000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b00001c8e0000413d000000000705004b00001ca50000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f000300000001035500000001022001900000000e0500002900001cd50000613d0000001f01400039000000600210018f0000000001a20019000000000221004b0000000002000019000000010200403900000cf60410009c00001ccf0000213d000000010220019000001ccf0000c13d000000400010043f000000200230008c00001bab0000413d00000000020a0433000000000302004b0000000003000019000000010300c039000000000332004b00001bab0000c13d000000000202004b00001d400000c13d000000440210003900000d8303000041000000000032043500000d4d0200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa0001043000000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000000400200043d0000001f0430018f000000050330027200001ce20000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b00001cda0000413d000000000504004b00001cf10000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa0001043000000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa0001043000000d550100004100000000001004350000003201000039000000040010043f00000d5601000041000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000440210003900000d7d03000041000000000032043500000024021000390000001c03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d7e030000410000000000320435000000440210003900000d7f03000041000000000032043500000024021000390000002503000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000020021000390000000d030000290000000000320435000000000051043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000112019f00000d74011001c70000800d02000039000000030300003900000d82040000410000000505000029000000000605001933a8339e0000040f000000010120019000001bab0000613d0000000102000029000000000102041a0000000203000029000000000131016f00000001011001bf000000000012041b0000000001000019000033a90001042e00030000000000020000000001000416000000000101004b00001dcc0000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b00001dcc0000c13d00000002010003670000000402100370000000000402043b00000cee0240009c00001dcc0000213d0000002401100370000000000501043b000000000105004b0000000001000019000000010100c039000000000115004b00001dcc0000c13d0000000002000411000000000142004b00001d910000c13d000000400100043d000000440210003900000dbd03000041000000000032043500000024021000390000001903000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000100000002001d00000000002004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c70000801002000039000300000004001d000200000005001d33a833a30000040f0000000303000029000000010220019000001dcc0000613d000000000101043b0000000000300435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000002040000290000000306000029000000010220019000001dcc0000613d000000000101043b000000000201041a000001000300008a000000000232016f000000000242019f000000000021041b000000400100043d000000000041043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000112019f00000cf7011001c70000800d02000039000000030300003900000dbc04000041000000010500002933a8339e0000040f000000010120019000001dcc0000613d0000000001000019000033a90001042e0000000001000019000033aa00010430000c0000000000020000000001000416000000000101004b00001de00000c13d000000040100008a000000000110003100000ced02000041000000400310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b00001de20000613d0000000001000019000033aa0001043000000002010003670000002402100370000000000502043b0000000401100370000000000401043b0000001903000039000000000103041a000000ff0210018f000000010220008c00001e170000c13d000a00000005001d000001000200008a000800000002001d000000000121016f000900000003001d000000000013041b000c00000004001d00000000004004350000000601000039000b00000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000001de00000613d000000000101043b000000000101041a00000cee0110019800001e2c0000c13d000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d72030000410000000000320435000000440210003900000d7303000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000700000001001d0000000c0100002900000000001004350000000b01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000001de00000613d000000000101043b000000000101041a00000cee0110019800001e050000613d0000000002000411000600000002001d00000cee03200197000000000213004b00001e5b0000c13d0000000c0100002900000000001004350000001401000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000001de00000613d000000400200043d00000d790320009c00001eb20000413d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000500000003001d00000000001004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000001de00000613d000000000101043b00000005020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000001de00000613d000000000101043b000000000101041a000000ff0110019000001e440000c13d0000000c0100002900000000001004350000000b01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000001de00000613d000000000101043b000000000101041a00000cee0110019800001e050000613d0000000c0100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000001de00000613d000000000101043b000000000101041a00000cee011001970000000502000029000000000121004b00001e440000613d000000400100043d000000440210003900000dbe03000041000000000032043500000d4d0200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000000101043b0000006003200039000000400030043f000000000301041a00000000033204360000000104100039000000000404041a00000000004304350000000201100039000000000601041a0000004001200039000000000061043500000000010204330000000a05000029000000000251004b00001ed90000a13d000000000205004b00001eee0000c13d000000400100043d000000640210003900000dc3030000410000000000320435000000440210003900000dc003000041000000000032043500000024021000390000002703000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000dbf030000410000000000320435000000440210003900000dc003000041000000000032043500000024021000390000002203000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000000425600a90000000007030433000000000306004b00001ef50000613d00000000436200d9000000000353004b00001ef90000c13d00000000231200d9000b00000003001d000000000236004b00001eff0000813d00000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa000104300000000001510049000300000001001d0000000c01000029000200000006001d000500000007001d33a82a6a0000040f0000000f01000039000100000001001d000000000101041a000400000001001d00000006010000290000000a020000290000000b03000029000000050400002933a8275a0000040f00000002010000290000000b0200002900000000032100490000000101000029000000000101041a000b00000001001d00000006010000290000000302000029000000050400002933a8275a0000040f000000400100043d0000000c02000029000000000221043600000040031000390000000b0400002900000000004304350000000403000029000000000032043500000ceb02000041000000000300041400000ceb0430009c000000000302801900000ceb0410009c00000000010280190000004001100210000000c002300210000000000112019f00000d8a011001c70000800d02000039000000030300003900000dc1040000410000000605000029000000070600002933a8339e0000040f000000010120019000001de00000613d0000000902000029000000000102041a0000000803000029000000000131016f00000001011001bf000000000012041b000000400100043d00000020021000390000000b0300002900000000003204350000000402000029000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000dc2011001c7000033a90001042e00050000000000020000000001000416000000000101004b0000203c0000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b0000203c0000c13d0000001101000039000000000101041a000500000001001d00000004010000390000000201100367000000000101043b000400000001001d00000000001004350000001401000039000300000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000050300002900000cee03300197000500000003001d00000001022001900000203c0000613d000000000101043b000000000101041a000200000001001d000000040100002900000000001004350000000301000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000203c0000613d000000000101043b0000000201100039000000000101041a000100000001001d000000040100002900000000001004350000000301000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000203c0000613d000000000101043b0000000101100039000000000101041a000000400800043d0000006402800039000000000012043500000044018000390000000102000029000000000021043500000024018000390000000202000029000000000021043500000dc401000041000000000018043500000004018000390000000402000029000000000021043500000000010004140000000502000029000000040320008c00001fa90000c13d0000000301000367000000010300003100001fbd0000013d00000ceb0400004100000ceb0310009c000000000104801900000ceb0380009c000000000304001900000000030840190000004003300210000000c001100210000000000131019f00000d54011001c7000500000008001d33a833a30000040f00000005080000290000000003010019000000600330027000010ceb0030019d00000ceb0330019700030000000103550000000102200190000020110000613d0000001f0230018f000000050430027200001fc90000613d000000000500001900000005065002100000000007680019000000000661034f000000000606043b00000000006704350000000105500039000000000645004b00001fc10000413d000000000502004b00001fd80000613d0000000504400210000000000141034f00000000044800190000000302200210000000000504043300000000052501cf000000000525022f000000000101043b0000010002200089000000000121022f00000000012101cf000000000151019f00000000001404350000001f02300039000000200100008a000000000412016f0000000002840019000000000442004b0000000004000019000000010400403900000cf60520009c0000200b0000213d00000001044001900000200b0000c13d00000ced04000041000000200530008c0000000005000019000000000504401900000ced06300197000000000706004b000000000400a01900000ced0660009c000000000405c019000000400020043f000000000404004b0000203c0000c13d000000000408043300000cf60540009c0000203c0000213d000000000583001900000000038400190000001f0430003900000ced06000041000000000754004b0000000007000019000000000706801900000ced0440019700000ced08500197000000000984004b0000000006008019000000000484013f00000ced0440009c00000000040700190000000004066019000000000404004b0000203c0000c13d000000004303043400000cf60630009c0000200b0000213d0000003f06300039000000000116016f000000000121001900000cf60610009c000020370000a13d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000000400200043d0000001f0430018f00000005033002720000201e0000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000020160000413d000000000504004b0000202d0000613d0000000503300210000000000131034f00000000033200190000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000ceb01000041000000010300003100000ceb0430009c000000000301801900000ceb0420009c000000000102401900000040011002100000006002300210000000000112019f000033aa00010430000000400010043f00000000013204360000000006430019000000000556004b0000203e0000a13d0000000001000019000033aa00010430000000000503004b000020480000613d000000000500001900000000061500190000000007450019000000000707043300000000007604350000002005500039000000000635004b000020410000413d00000000011300190000000000010435000000400100043d000500000001001d33a809c70000040f0000000504000029000000000141004900000ceb0200004100000ceb0310009c000000000102801900000ceb0340009c000000000204401900000040022002100000006001100210000000000121019f000033a90001042e00070000000000020000000001000416000000000101004b000020f60000c13d000000040100008a000000000110003100000ced02000041000000200310008c0000000003000019000000000302401900000ced01100197000000000401004b000000000200a01900000ced0110009c00000000010300190000000001026019000000000101004b000020f60000c13d00000004010000390000000201100367000000000101043b000500000001001d00000cee0110009c000020f60000213d0000000502000029000000000102004b000020880000c13d000000400100043d000000640210003900000da2030000410000000000320435000000440210003900000da303000041000000000032043500000024021000390000002903000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000000002004350000000701000039000300000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000020f60000613d000000000101043b000000000101041a000200000001001d000000000101004b0000000002000019000020a40000c13d000000400100043d000000000021043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4b011001c7000033a90001042e0000801001000039000600000001001d0000000a01000039000100000001001d0000000002000019000700000000001d000400000002001d000000050100002900000000001004350000000301000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000000060200002933a833a30000040f0000000102200190000020f60000613d000000000101043b000000000101041a0000000702000029000000000121004b000020f80000a13d000000050100002900000000001004350000000101000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000000060200002933a833a30000040f0000000102200190000020f60000613d000000000101043b00000007020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000000060200002933a833a30000040f0000000102200190000020f60000613d000000000101043b000000000101041a00000000001004350000001401000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000020f60000613d000000000101043b0000000201100039000000000101041a0000000402000029000000000212001a0000210d0000413d000000070300002900000001033000390000000201000029000700000003001d000000000113004b000020aa0000413d0000209c0000013d0000000001000019000033aa00010430000000400100043d000000640210003900000da0030000410000000000320435000000440210003900000da103000041000000000032043500000024021000390000002b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa0001043000000cee022001970000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000021220000613d000000000101043b000000000001042d0000000001000019000033aa0001043000000cee01100198000021360000613d00000000001004350000000701000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000214b0000613d000000000101043b000000000101041a000000000001042d000000400100043d000000640210003900000da2030000410000000000320435000000440210003900000da303000041000000000032043500000024021000390000002903000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300000000001000019000033aa0001043000000000001004350000000601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000215f0000613d000000000101043b000000000101041a00000cee01100198000021610000613d000000000001042d0000000001000019000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000000101004b000021760000613d000000000001042d000000400100043d000000640210003900000dc5030000410000000000320435000000440210003900000dc603000041000000000032043500000024021000390000003d03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300001000000000002000100000001001d00000000001004350000000601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000021b00000613d000000000101043b000000000101041a00000cee01100198000021b20000613d000000010100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000021b00000613d000000000101043b000000000101041a00000cee01100197000000000001042d0000000001000019000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000000101004b000021c70000613d000000000001042d000000400100043d000000640210003900000dc7030000410000000000320435000000440210003900000dc803000041000000000032043500000024021000390000002d03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300006000000000002000300000004001d000500000002001d000400000001001d000600000003001d00000000003004350000000601000039000100000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022490000613d000000000101043b000000000101041a00000cee011001980000224b0000613d000000000200041100000cee02200197000200000002001d000000000212004b0000223d0000613d00000000001004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022490000613d000000000101043b00000002020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022490000613d000000000101043b000000000101041a000000ff011001900000223d0000c13d000000060100002900000000001004350000000101000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022490000613d000000000101043b000000000101041a00000cee011001980000224b0000613d000000060100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022490000613d000000000101043b000000000101041a00000cee011001970000000202000029000000000121004b0000226e0000c13d00000004010000290000000502000029000000060300002933a823060000040f000000040100002900000005020000290000000603000029000000030400002933a8260a0000040f000000000101004b0000225d0000613d000000000001042d0000000001000019000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400200043d000600000002001d00000d4d010000410000000000120435000000040120003933a822830000040f0000000604000029000000000141004900000ceb0200004100000ceb0310009c000000000102801900000ceb0340009c000000000204401900000040022002100000006001100210000000000121019f000033aa00010430000000400100043d000000640210003900000dc7030000410000000000320435000000440210003900000dc803000041000000000032043500000024021000390000002d03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000600210003900000dc9030000410000000000320435000000400210003900000dca030000410000000000320435000000200210003900000032030000390000000000320435000000200200003900000000002104350000008001100039000000000001042d0003000000000002000300000001001d000200000002001d00000000002004350000000601000039000100000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022f20000613d000000000101043b000000000101041a00000cee02100198000022f40000613d0000000101000039000000030300002900000cee03300197000300000003001d000000000323004b000022f10000613d00000000002004350000000901000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022f20000613d000000000101043b00000003020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022f20000613d000000000101043b000000000101041a000000ff01100190000022f10000c13d000000020100002900000000001004350000000101000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022f20000613d000000000101043b000000000101041a00000cee01100198000022f40000613d000000020100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000022f20000613d000000000101043b000000000101041a00000cee011001970000000302000029000000000121004b00000000010000190000000101006039000000000001042d0000000001000019000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa000104300009000000000002000700000002001d000800000001001d000900000003001d00000000003004350000000601000039000600000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000101041a00000cee02100198000024900000613d000000080100002900000cee01100197000000000112004b000024a20000c13d000000070100002900000cee03100198000024b70000613d000000000132004b000800000002001d000700000003001d000023cf0000613d00000000002004350000000701000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000101041a000400000001001d000000000101004b000024cc0000613d000000090100002900000000001004350000000b01000039000500000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d0000000402000029000000010220008a000000000101043b000000000301041a000400000002001d000000000123004b0000239f0000613d000300000003001d000000080100002900000000001004350000000a01000039000200000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b00000004020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000101041a000100000001001d000000080100002900000000001004350000000201000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b00000003020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b0000000102000029000000000021041b00000000002004350000000501000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b0000000302000029000000000021041b000000090100002900000000001004350000000501000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000001041b000000080100002900000000001004350000000a01000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b00000004020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000001041b00000008020000290000000703000029000000000123004b000024110000613d000000070100002900000000001004350000000701000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000101041a000500000001001d000000070100002900000000001004350000000a01000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b00000005020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b0000000902000029000000000021041b00000000002004350000000b01000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b0000000502000029000000000021041b000000090100002900000000001004350000000601000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000101041a00000cee011001980000000802000029000024900000613d000000000121004b000024a20000c13d000000090100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000201041a00000cf302200197000000000021041b000000080100002900000000001004350000000701000039000500000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000201041a000000010220008a000000000021041b000000070100002900000000001004350000000501000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000201041a0000000102200039000000000021041b000000090100002900000000001004350000000601000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000248e0000613d000000000101043b000000000201041a00000cf3022001970000000706000029000000000262019f000000000021041b00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf4011001c70000800d02000039000000040300003900000dcd040000410000000805000029000000090700002933a8339e0000040f00000001012001900000248e0000613d000000090100002900000000001004350000001401000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001012001900000248e0000613d000000000001042d0000000001000019000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000dcb030000410000000000320435000000440210003900000dcc03000041000000000032043500000024021000390000002503000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000dce030000410000000000320435000000440210003900000dcf03000041000000000032043500000024021000390000002403000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa000104300002000000000002000100000001001d000200000002001d00000000002004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000250b0000613d000000010200002900000cee03200197000000000101043b000000000201041a00000cf302200197000100000003001d000000000232019f000000000021041b000000020100002900000000001004350000000601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000250b0000613d0000000207000029000000000101043b000000000101041a00000cee051001980000250d0000613d00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf4011001c70000800d02000039000000040300003900000dd004000041000000010600002933a8339e0000040f00000001012001900000250b0000613d000000000001042d0000000001000019000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa000104300005000000000002000200000003001d000100000002001d00000dd1020000410000000000200439000300000001001d000000040010044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000dd2011001c7000080020200003933a833a30000040f000000000301034f0000000101200190000025b70000613d0000000101000039000000000203043b000000000202004b000025b60000613d000000400a00043d0000006401a00039000000800200003900000000002104350000004401a000390000000102000029000000000021043500000dd30100004100000000001a0435000000000100041100000cee011001970000000402a0003900000000001204350000002401a000390000000000010435000000020600002900000000010604330000008402a000390000000000120435000000a402a00039000000000301004b000025530000613d000000000300001900000000042300190000002003300039000000000563001900000000050504330000000000540435000000000413004b0000254c0000413d000000000221001900000000000204350000000003000414000000030200002900000cee02200197000000040420008c000025630000c13d0000000001000415000000050110008a00000020011000c90000000103000031000000200230008c00000020040000390000000004034019000500000000001d000025a00000013d0000001f01100039000000200400008a000000000141016f00000ceb0400004100000ceb05a0009c000000000504001900000000050a40190000004005500210000000a40110003900000ceb0610009c00000000010480190000006001100210000000000151019f00000ceb0530009c0000000003048019000000c003300210000000000113019f00030000000a001d33a8339e0000040f000000030a0000290000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000506400272000025890000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000025810000413d000000000705004b000025980000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000001000415000000040110008a00000020011000c9000400000000001d0000000102200190000025b90000613d0000001f02400039000000600420018f0000000002a40019000000000442004b0000000004000019000000010400403900000cf60520009c000025fb0000213d0000000104400190000025fb0000c13d000000400020043f000000200230008c000025b70000413d00000000020a043300000d6b03200197000000000323004b000025b70000c13d000000200110011a000000000102001f00000dd30120009c00000000010000190000000101006039000000000001042d0000000001000019000033aa000104300000006001000039000000000203004b000025d00000c13d0000000021010434000000000301004b000026010000c13d000000400200043d000300000002001d00000d4d010000410000000000120435000000040120003933a822830000040f0000000304000029000000000141004900000ceb0200004100000ceb0310009c000000000102801900000ceb0340009c000000000204401900000040022002100000006001100210000000000121019f000033aa000104300000003f0130003900000dd402100197000000400100043d0000000002210019000000000412004b0000000004000019000000010400403900000cf60520009c000025fb0000213d0000000104400190000025fb0000c13d000000400020043f0000000002310436000000030300036700000001050000310000001f0450018f0000000505500272000025eb0000613d000000000600001900000005076002100000000008720019000000000773034f000000000707043b00000000007804350000000106600039000000000756004b000025e30000413d000000000604004b000025bc0000613d0000000505500210000000000353034f00000000025200190000000304400210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000025bc0000013d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa0001043000000ceb0300004100000ceb0420009c000000000203801900000ceb0410009c000000000103801900000060011002100000004002200210000000000121019f000033aa000104300006000000000002000300000004001d000200000003001d000100000001001d00000dd1010000410000000000100439000400000002001d000000040020044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000dd2011001c7000080020200003933a833a30000040f000000000301034f0000000101200190000026a50000613d0000000101000039000000000203043b000000000202004b000026a40000613d000000400a00043d0000006401a00039000000800200003900000000002104350000004401a0003900000002020000290000000000210435000000010100002900000cee011001970000002402a00039000000000012043500000dd30100004100000000001a0435000000000100041100000cee011001970000000402a000390000000000120435000000030600002900000000010604330000008402a000390000000000120435000000a402a00039000000000301004b000026410000613d000000000300001900000000042300190000002003300039000000000563001900000000050504330000000000540435000000000413004b0000263a0000413d000000000221001900000000000204350000000003000414000000040200002900000cee02200197000000040420008c000026510000c13d0000000001000415000000060110008a00000020011000c90000000103000031000000200230008c00000020040000390000000004034019000600000000001d0000268e0000013d0000001f01100039000000200400008a000000000141016f00000ceb0400004100000ceb05a0009c000000000504001900000000050a40190000004005500210000000a40110003900000ceb0610009c00000000010480190000006001100210000000000151019f00000ceb0530009c0000000003048019000000c003300210000000000113019f00040000000a001d33a8339e0000040f000000040a0000290000000003010019000000600330027000000ceb03300197000000200430008c000000200400003900000000040340190000001f0540018f0000000506400272000026770000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b0000266f0000413d000000000705004b000026860000613d0000000506600210000000000761034f00000000066a00190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000100000003001f00030000000103550000000001000415000000050110008a00000020011000c9000500000000001d0000000102200190000026a70000613d0000001f02400039000000600420018f0000000002a40019000000000442004b0000000004000019000000010400403900000cf60520009c000026e90000213d0000000104400190000026e90000c13d000000400020043f000000200230008c000026a50000413d00000000020a043300000d6b03200197000000000323004b000026a50000c13d000000200110011a000000000102001f00000dd30120009c00000000010000190000000101006039000000000001042d0000000001000019000033aa000104300000006001000039000000000203004b000026be0000c13d0000000021010434000000000301004b000026ef0000c13d000000400200043d000400000002001d00000d4d010000410000000000120435000000040120003933a822830000040f0000000404000029000000000141004900000ceb0200004100000ceb0310009c000000000102801900000ceb0340009c000000000204401900000040022002100000006001100210000000000121019f000033aa000104300000003f0130003900000dd402100197000000400100043d0000000002210019000000000412004b0000000004000019000000010400403900000cf60520009c000026e90000213d0000000104400190000026e90000c13d000000400020043f0000000002310436000000030300036700000001050000310000001f0450018f0000000505500272000026d90000613d000000000600001900000005076002100000000008720019000000000773034f000000000707043b00000000007804350000000106600039000000000756004b000026d10000413d000000000604004b000026aa0000613d0000000505500210000000000353034f00000000025200190000000304400210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000026aa0000013d00000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa0001043000000ceb0300004100000ceb0420009c000000000203801900000ceb0410009c000000000103801900000060011002100000004002200210000000000121019f000033aa000104300002000000000002000200000002001d00000cee01100198000027300000613d000100000001001d00000000001004350000000701000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000272e0000613d000000000101043b000000000101041a0000000202000029000000000121004b000027450000a13d000000010100002900000000001004350000000a01000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000272e0000613d000000000101043b00000002020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f00000001022001900000272e0000613d000000000101043b000000000101041a000000000001042d0000000001000019000033aa00010430000000400100043d000000640210003900000da2030000410000000000320435000000440210003900000da303000041000000000032043500000024021000390000002903000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000da0030000410000000000320435000000440210003900000da103000041000000000032043500000024021000390000002b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000c000000000002000800000003001d000700000001001d0000000f01000039000300000001001d000000000101041a000c00000001001d000000400300043d00000d790130009c000029d90000813d0000006001300039000000400010043f00000040053000390000000801000029000a00000005001d0000000000150435000b00000003001d0000000001230436000900000001001d00000000004104350000000c0100002900000000001004350000001401000039000400000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d0000000b020000290000000002020433000000000101043b000000000021041b000000090200002900000000020204330000000103100039000000000023041b00000002011000390000000a020000290000000002020433000000000021041b000000400100043d000600000001001d00000dba0110009c000029d90000213d00000006020000290000002001200039000000400010043f0000000000020435000000070100002900000cee01100198000b00000001001d00002a210000613d0000000c0100002900000000001004350000000601000039000a00000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b000000000101041a00000cee01100198000029e50000c13d0000000c01000039000500000001001d000000000101041a000900000001001d0000000c0100002900000000001004350000000d01000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b0000000902000029000000000021041b00000cf60120009c000029d90000213d00000001012000390000000503000029000000000013041b000000000030043500000d68012000410000000c02000029000000000021041b0000000b0100002900000000001004350000000701000039000500000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b000000000101041a000900000001001d0000000b0100002900000000001004350000000a01000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b00000009020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b0000000c02000029000000000021041b00000000002004350000000b01000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b0000000902000029000000000021041b0000000c0100002900000000001004350000000a01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b000000000101041a00000cee01100198000029e50000c13d0000000b0100002900000000001004350000000501000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b000000000201041a0000000102200039000000000021041b0000000c0100002900000000001004350000000a01000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b000000000201041a00000cf3022001970000000b06000029000000000262019f000000000021041b00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf4011001c70000800d02000039000000040300003900000dcd0400004100000000050000190000000c0700002933a8339e0000040f0000000101200190000029d70000613d0000000c0100002900000000001004350000000401000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b0000000201100039000000000101041a000a00000001001d00000dd60110009c00002a320000813d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000029d70000613d000000000201043b00000d5e0120009c000029f70000813d00000dd70120009c00002a0c0000813d0000001701000039000000000301041a000000000403004b00000000040000190000287b0000613d000000000010043500000dd803300041000000000303041a00000020043002700000000a03000029000000000334001900000dd60430009c000029df0000813d000000000401041a000000000504004b000028950000613d000000000010043500000dd804400041000000400500043d00000cef0650009c000029d90000213d0000004006500039000000400060043f000000000604041a00000020075000390000002008600270000000000087043500000ceb066001970000000000650435000000000526004b00002a470000213d000000000526004b000028ab0000c13d0000000000100435000028c00000013d000000400400043d00000cef0540009c000029d90000213d0000004005400039000000400050043f00000000022404360000000000320435000000000301041a00000cf60530009c000029d90000213d0000000105300039000000000051041b0000000000100435000000000104043300000ceb0110019700000dd904300041000000000304041a00000dda03300197000000000113019f000000000014041b0000000003020433000028c00000013d000000400400043d00000cef0540009c000029d90000213d0000004005400039000000400050043f00000000022404360000000000320435000000000301041a00000cf60530009c000029d90000213d0000000105300039000000000051041b0000000000100435000000000104043300000ceb0110019700000dd904300041000000000304041a00000dda03300197000000000113019f000000000014041b00000000030204330000002001300210000000000204041a00000ceb02200197000000000112019f000000000014041b0000000c0100002900000000001004350000001501000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b000000000201041a00000cf3022001970000000b03000029000000000232019f000000000021041b0000000a01000029000000000101004b000029c60000613d0000000b0100002900000000001004350000001601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b000900000001001d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000029d70000613d000000000401043b00000d5d0140009c000029f70000213d00000ceb0140009c000000090300002900002a0c0000213d000000000203041a000000000102004b0000000001000019000500000004001d000029170000613d000400000002001d000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b00000004020000290000000001120019000000010110008a000000000101041a0000002001100270000000090300002900000005040000290000000a020000290000000001210019000a00000001001d00000d580110009c000029df0000213d000000000203041a000000000102004b000029530000613d000400000002001d000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000400200043d00000cef0320009c00000009040000290000000505000029000029d90000213d0000000403000029000000010730008a000000000101043b0000004003200039000000400030043f0000000001710019000000000101041a00000020031002700000002006200039000000000036043500000ceb011001970000000000120435000000000251004b00002a470000213d000000000151004b000400000006001d000029810000c13d000500000007001d000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b000000050200002900000000012100190000000a020000290000000404000029000029a90000013d000000400200043d00000cef0120009c000029d90000213d0000004001200039000000400010043f00000000044204360000000a01000029000900000004001d0000000000140435000000000403041a00000cf60140009c000029d90000213d000500000002001d000400000004001d0000000101400039000000000013041b000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b00000004020000290000000001210019000000000201041a00000dda022001970000000503000029000000000303043300000ceb03300197000000000232019f000000000021041b000000000201041a00000ceb02200197000000090300002900000000030304330000002003300210000000000232019f000000000021041b0000000001000019000029b00000013d000000400200043d00000cef0120009c000029d90000213d0000004001200039000000400010043f00000000035204360000000a01000029000500000003001d0000000000130435000000000304041a00000cf60130009c000029d90000213d000200000002001d000100000003001d0000000101300039000000000014041b000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000029d70000613d000000000101043b00000001020000290000000001210019000000000201041a00000dda022001970000000203000029000000000303043300000ceb03300197000000000232019f000000000021041b0000000502000029000000000202043300000004040000290000002002200210000000000301041a00000ceb03300197000000000223019f000000000021041b000000000104043300000d5801100197000000400200043d00000020032000390000000a040000290000000000430435000000000012043500000ceb01000041000000000300041400000ceb0430009c000000000301801900000ceb0420009c00000000010240190000004001100210000000c002300210000000000112019f00000d74011001c70000800d02000039000000020300003900000ddc040000410000000b0500002933a8339e0000040f0000000101200190000029d70000613d00000007010000290000000c02000029000000060300002933a8251f0000040f000000000101004b00002a590000613d0000001201000039000000000201041a0000000803000029000000000232001a000029df0000413d000000000021041b0000000302000029000000000102041a0000000101100039000000000012041b000000000001042d0000000001000019000033aa0001043000000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa0001043000000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa00010430000000400100043d000000440210003900000dd503000041000000000032043500000024021000390000001c03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000d61030000410000000000320435000000440210003900000d6203000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000ddd030000410000000000320435000000440210003900000dde03000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000440210003900000de103000041000000000032043500000d4d0200004100000000002104350000002402100039000000200300003900000000003204350000000402100039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400100043d000000640210003900000ddf030000410000000000320435000000440210003900000de003000041000000000032043500000024021000390000002703000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000440210003900000ddb03000041000000000032043500000024021000390000001b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa00010430000000400200043d000c00000002001d00000d4d010000410000000000120435000000040120003933a822830000040f0000000c04000029000000000141004900000ceb0200004100000ceb0310009c000000000102801900000ceb0340009c000000000204401900000040022002100000006001100210000000000121019f000033aa000104300009000000000002000900000001001d00000000001004350000000601000039000700000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000101041a00000cee0110019800002dca0000613d000800000001001d00000000001004350000000701000039000400000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000101041a000500000001001d000000000101004b00002dbe0000613d000000090100002900000000001004350000000b01000039000600000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d0000000502000029000000010220008a000000000101043b000000000301041a000500000002001d000000000123004b00002af80000613d000300000003001d000000080100002900000000001004350000000a01000039000200000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b00000005020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000101041a000100000001001d000000080100002900000000001004350000000201000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b00000003020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b0000000102000029000000000021041b00000000002004350000000601000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b0000000302000029000000000021041b000000090100002900000000001004350000000601000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000001041b000000080100002900000000001004350000000a01000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b00000005020000290000000000200435000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000001041b0000000c01000039000800000001001d000000000101041a000500000001001d000000000101004b00002dbe0000613d000000090100002900000000001004350000000d01000039000600000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d0000000603000029000000000101043b000000000401041a000000080100002900000000001004350000000502000029000000000124004b00002e0c0000813d000300000004001d00000d680140004100000de202200041000000000202041a000000000021041b0000000000200435000000200030043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b0000000302000029000000000021041b000000090100002900000000001004350000000601000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000001041b0000000803000029000000000103041a000000000201004b00002e120000613d000000000030043500000de202100041000000000002041b000000010110008a000000000013041b000000090100002900000000001004350000000701000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000101041a00000cee01100198000800000001001d00002dca0000613d000000090100002900000000001004350000000801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000201041a00000cf302200197000000000021041b000000080100002900000000001004350000000401000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000201041a000000010220008a000000000021041b000000090100002900000000001004350000000701000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000201041a00000cf302200197000000000021041b00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf4011001c70000800d02000039000000040300003900000dcd0400004100000008050000290000000006000019000000090700002933a8339e0000040f000000010120019000002dbc0000613d000000090100002900000000001004350000001401000039000700000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b0000000201100039000000000101041a000800000001001d00000d580110009c00002e180000213d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f000000010220019000002dbc0000613d000000000201043b00000d5d0120009c00002de20000213d00000ceb0120009c00002df70000213d0000001701000039000000000301041a000000000403004b000000000400001900002bf70000613d000000000010043500000dd803300041000000000303041a00000020043002700000000803000029000000000334004900000d580430009c00002dbe0000213d000000000401041a000000000504004b00002c110000613d000000000010043500000dd804400041000000400500043d00000cef0650009c00002dc40000213d0000004006500039000000400060043f000000000604041a00000020075000390000002008600270000000000087043500000ceb066001970000000000650435000000000526004b00002e2d0000213d000000000526004b00002c270000c13d000000000010043500002c3c0000013d000000400400043d00000cef0540009c00002dc40000213d0000004005400039000000400050043f00000000022404360000000000320435000000000301041a00000cf60530009c00002dc40000213d0000000105300039000000000051041b0000000000100435000000000104043300000ceb0110019700000dd904300041000000000304041a00000dda03300197000000000113019f000000000014041b000000000302043300002c3c0000013d000000400400043d00000cef0540009c00002dc40000213d0000004005400039000000400050043f00000000022404360000000000320435000000000301041a00000cf60530009c00002dc40000213d0000000105300039000000000051041b0000000000100435000000000104043300000ceb0110019700000dd904300041000000000304041a00000dda03300197000000000113019f000000000014041b00000000030204330000002001300210000000000204041a00000ceb02200197000000000112019f000000000014041b000000090100002900000000001004350000001501000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000101041a00000cee01100198000600000001001d00002d410000613d0000000801000029000000000101004b00002d410000613d000000060100002900000000001004350000001601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000500000001001d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f000000010220019000002dbc0000613d000000000401043b00000d5d0140009c00002de20000213d00000ceb0140009c000000050300002900002df70000213d000000000203041a000000000102004b0000000001000019000400000004001d00002c920000613d000300000002001d000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b00000003020000290000000001120019000000010110008a000000000101041a00000020011002700000000503000029000000040400002900000008020000290000000001210049000800000001001d00000d580110009c00002dbe0000213d000000000203041a000000000102004b00002cce0000613d000300000002001d000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000400200043d00000cef0320009c0000000504000029000000040500002900002dc40000213d0000000303000029000000010730008a000000000101043b0000004003200039000000400030043f0000000001710019000000000101041a00000020031002700000002006200039000000000036043500000ceb011001970000000000120435000000000251004b00002e2d0000213d000000000151004b000300000006001d00002cfc0000c13d000400000007001d000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000040200002900000000012100190000000802000029000000030400002900002d240000013d000000400200043d00000cef0120009c00002dc40000213d0000004001200039000000400010043f00000000044204360000000801000029000500000004001d0000000000140435000000000403041a00000cf60140009c00002dc40000213d000400000002001d000300000004001d0000000101400039000000000013041b000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b00000003020000290000000001210019000000000201041a00000dda022001970000000403000029000000000303043300000ceb03300197000000000232019f000000000021041b000000000201041a00000ceb02200197000000050300002900000000030304330000002003300210000000000232019f000000000021041b000000000100001900002d2b0000013d000000400200043d00000cef0120009c00002dc40000213d0000004001200039000000400010043f00000000035204360000000801000029000400000003001d0000000000130435000000000304041a00000cf60130009c00002dc40000213d000200000002001d000100000003001d0000000101300039000000000014041b000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b00000001020000290000000001210019000000000201041a00000dda022001970000000203000029000000000303043300000ceb03300197000000000232019f000000000021041b0000000402000029000000000202043300000003040000290000002002200210000000000301041a00000ceb03300197000000000223019f000000000021041b000000000104043300000d5801100197000000400200043d000000200320003900000008040000290000000000430435000000000012043500000ceb01000041000000000300041400000ceb0430009c000000000301801900000ceb0420009c00000000010240190000004001100210000000c002300210000000000112019f00000d74011001c70000800d02000039000000020300003900000ddc04000041000000060500002933a8339e0000040f000000010120019000002dbc0000613d000000090100002900000000001004350000000e01000039000800000001001d000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b000000000101041a000000010210019000000001011002700000007f0310018f00000000010360190000001f0310008c00000000030000190000000103002039000000010330018f000000000232004b00002ddc0000c13d000000000101004b00002da40000613d000000090100002900000000001004350000000801000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000401043b000000000104041a000000010210019000000001021002700000007f0320018f000000000302c0190000001f0230008c00000000020000190000000102002039000000000121013f000000010110019000002ddc0000c13d000000000103004b00002da40000613d0000001f0130008c00002da30000a13d000800000003001d000600000004001d000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000201043b00000008010000290000001f01100039000000050110027000000000011200190000000102200039000000000312004b00002d950000813d000000000002041b0000000102200039000000000312004b00002d910000413d00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d000000000101043b0000000602000029000000000002041b0000000004010019000000000004041b000000090100002900000000001004350000000701000029000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000010220019000002dbc0000613d0000001202000039000000000302041a000000000101043b0000000201100039000000000101041a000000000413004b00002dbe0000413d0000000001130049000000000012041b000000000001042d0000000001000019000033aa0001043000000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa0001043000000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000000400100043d000000440210003900000d7603000041000000000032043500000024021000390000001803000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa0001043000000d550100004100000000001004350000002201000039000000040010043f00000d5601000041000033aa00010430000000400100043d000000640210003900000d61030000410000000000320435000000440210003900000d6203000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000ddd030000410000000000320435000000440210003900000dde03000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000d550100004100000000001004350000003201000039000000040010043f00000d5601000041000033aa0001043000000d550100004100000000001004350000003101000039000000040010043f00000d5601000041000033aa00010430000000400100043d000000640210003900000ddf030000410000000000320435000000440210003900000de003000041000000000032043500000024021000390000002703000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000440210003900000ddb03000041000000000032043500000024021000390000001b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa0001043000000d5e0210009c00002e420000813d000000000001042d000000400100043d000000640210003900000d61030000410000000000320435000000440210003900000d6203000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa000104300001000000000002000000000301041a000000000203004b000000000200001900002e6e0000613d000100000003001d000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002e700000613d000000000101043b00000001020000290000000001120019000000010110008a000000000101041a00000020021002700000000001020019000000000001042d0000000001000019000033aa000104300000001702000039000000000302041a000000060430008c0000000005000019000000000403001900002eda0000413d000000800430027000000de30530009c000000000403a01900000de30530009c0000000005000019000000800500203900000040065001bf00000cf60740009c0000000005062019000000400640027000000cf60740009c000000000406201900000020065001bf00000ceb0740009c0000000005062019000000200640027000000ceb0740009c000000000406201900000010065001bf0000ffff0740008c0000000005062019000000100640027000000000040620190000000806500039000000ff0740008c00000000050620190000000806400270000000000406201900000004065000390000000f0740008c0000000005062019000000040640027000000000040620190000000206500039000000030740008c000000000506201900000002064002700000000004062019000000010440008c0000000004000019000000010400203900000000044500190000000104400270000000000543022f000000010440020f0000000004540019000000010540008c00002f000000a13d000000010440027000000000654300d90000000004450019000000020540008c00002f000000413d000000010440027000000000654300d90000000004450019000000020540008c00002f000000413d000000010440027000000000654300d90000000004450019000000020540008c00002f000000413d000000010440027000000000654300d90000000004450019000000020540008c00002f000000413d000000010440027000000000654300d90000000004450019000000020540008c00002f000000413d000000010440027000000000654300d90000000004450019000000020540008c00002f000000413d000000010440027000000000654300d9000000000654004b0000000004058019000000000543004b00002ef20000413d0000000004430049000000000020043500000ceb0510019700000dd906400041000000000606041a00000ceb06600197000000000565004b000000000500001900002eda0000413d000000010500008a000000000554004b00002ef20000613d00000001054000390000000004030019000000000345004b00002ef80000813d00000ceb01100197000000010300008a000000000604001900002ee50000013d00000001054000390000000004060019000000000645004b000000000604001900002ef80000813d000000000465016f000000000765013f0000000107700270000000000447001a00002ef20000413d000000000020043500000dd907400041000000000707041a00000ceb07700197000000000717004b00002ee20000213d000000000534004b00002ee00000c13d00000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa00010430000000000104004b000000000100001900002eff0000613d000000000020043500000dd801400041000000000101041a0000002001100270000000000001042d00000d550100004100000000001004350000001201000039000000040010043f00000d5601000041000033aa0001043000070000000000020000000005020019000400000001001d000000000601041a000000060160008c0000000002000019000000000406001900002f820000413d000000800160027000000de30260009c000000000106a01900000de30260009c0000000002000019000000800200203900000040032001bf00000cf60410009c0000000002032019000000400310027000000cf60410009c000000000103201900000020032001bf00000ceb0410009c0000000002032019000000200310027000000ceb0410009c000000000103201900000010032001bf0000ffff0410008c0000000002032019000000100310027000000000010320190000000803200039000000ff0410008c00000000020320190000000803100270000000000103201900000004032000390000000f0410008c0000000002032019000000040310027000000000010320190000000203200039000000030410008c000000000203201900000002031002700000000001032019000000010110008c0000000001000019000000010100203900000000011200190000000101100270000000000216022f000000010110020f0000000001210019000000010210008c00002fd00000a13d000000010110027000000000321600d90000000001120019000000020210008c00002fd00000413d000000010110027000000000321600d90000000001120019000000020210008c00002fd00000413d000000010110027000000000321600d90000000001120019000000020210008c00002fd00000413d000000010110027000000000321600d90000000001120019000000020210008c00002fd00000413d000000010110027000000000321600d90000000001120019000000020210008c00002fd00000413d000000010110027000000000321600d90000000001120019000000020210008c00002fd00000413d000000010110027000000000321600d9000000000321004b0000000001028019000700000001001d000000000116004b00002fb10000413d000500000006001d000600000005001d0000000401000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002fce0000613d000000050300002900000007020000290000000004230049000000000101043b0000000001410019000000000101041a00000ceb01100197000000060500002900000ceb02500197000000000112004b000000000200001900002f820000413d000000010100008a000000000114004b00002fb10000613d00000001024000390000000004030019000000000142004b00002fb70000813d00000ceb01500197000200000001001d0000801001000039000300000001001d000000010100008a000100000001001d000000000304001900002f910000013d00000001024000390000000504000029000000000142004b000000000304001900002fb70000813d000000000132016f000600000002001d000500000003001d000000000232013f0000000102200270000000000112001a00002fb10000413d000700000001001d0000000401000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000000030200002933a833a30000040f000000010220019000002fce0000613d000000000101043b00000007040000290000000001410019000000000101041a00000ceb011001970000000202000029000000000121004b000000060200002900002f8e0000213d0000000101000029000000000114004b00002f8c0000c13d00000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa00010430000000000104004b000000000100001900002fcd0000613d000700000004001d0000000401000029000000000010043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f000000010220019000002fce0000613d000000000101043b00000007020000290000000001120019000000010110008a000000000101041a0000002001100270000000000001042d0000000001000019000033aa0001043000000d550100004100000000001004350000001201000039000000040010043f00000d5601000041000033aa0001043000000dd70210009c00002fd90000813d000000000001042d000000400100043d000000640210003900000ddd030000410000000000320435000000440210003900000dde03000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000000101004b00002ff10000613d000000000001042d000000400100043d000000640210003900000de4030000410000000000320435000000440210003900000de503000041000000000032043500000024021000390000002303000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000000101004b000030090000613d000000000001042d000000400100043d000000640210003900000de6030000410000000000320435000000440210003900000de703000041000000000032043500000024021000390000002503000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000000101004b000030210000613d000000000001042d000000400100043d000000640210003900000de8030000410000000000320435000000440210003900000de903000041000000000032043500000024021000390000002303000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000000101004b000030390000613d000000000001042d000000400100043d000000440210003900000dea03000041000000000032043500000024021000390000001d03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa000104300009000000000002000700000002001d000800000001001d00000000001004350000001501000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b000000000101041a000900000001001d00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f000000090300002900000cee03300197000900000003001d0000000102200190000032790000613d000000070200002900000cee07200197000000000101043b000000000201041a00000cf302200197000000000272019f000000000021041b00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf4011001c70000800d02000039000000040300003900000deb0400004100000009050000290000000806000029000800000007001d33a8339e0000040f0000000101200190000032790000613d0000001401000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b0000000201100039000000000101041a000700000001001d00000008010000290000000902000029000000000112004b000032780000613d0000000701000029000000000101004b000032780000613d0000000901000029000000000101004b000031880000613d000000090100002900000000001004350000001601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b000600000001001d000000070100002900000dd60110009c000032810000813d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000032790000613d000000000401043b00000d5e0140009c000032960000813d00000dd70140009c0000000603000029000032ab0000813d000000000203041a000000000102004b0000000001000019000400000004001d000030d90000613d000500000002001d000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b00000005020000290000000001120019000000010110008a000000000101041a00000020011002700000000603000029000000040400002900000007020000290000000001210049000500000001001d00000dd60110009c000032c00000813d000000000203041a000000000102004b000031150000613d000300000002001d000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000400200043d00000cef0320009c000000060400002900000004050000290000327b0000213d0000000303000029000000010730008a000000000101043b0000004003200039000000400030043f0000000001710019000000000101041a00000020031002700000002006200039000000000036043500000ceb011001970000000000120435000000000251004b000032c60000213d000000000151004b000300000006001d000031430000c13d000400000007001d000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b00000004020000290000000001210019000000050200002900000003040000290000316b0000013d000000400200043d00000d7a0120009c0000327b0000813d0000004001200039000000400010043f00000000044204360000000501000029000600000004001d0000000000140435000000000403041a00000cf60140009c0000327b0000213d000400000002001d000300000004001d0000000101400039000000000013041b000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b00000003020000290000000001210019000000000201041a00000dda022001970000000403000029000000000303043300000ceb03300197000000000232019f000000000021041b000000000201041a00000ceb02200197000000060300002900000000030304330000002003300210000000000232019f000000000021041b0000000001000019000031720000013d000000400200043d00000cef0120009c0000327b0000213d0000004001200039000000400010043f00000000035204360000000501000029000400000003001d0000000000130435000000000304041a00000cf60130009c0000327b0000213d000200000002001d000100000003001d0000000101300039000000000014041b000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b00000001020000290000000001210019000000000201041a00000dda022001970000000203000029000000000303043300000ceb03300197000000000232019f000000000021041b0000000402000029000000000202043300000003040000290000002002200210000000000301041a00000ceb03300197000000000223019f000000000021041b000000000104043300000d5801100197000000400200043d000000200320003900000005040000290000000000430435000000000012043500000ceb01000041000000000300041400000ceb0430009c000000000301801900000ceb0420009c00000000010240190000004001100210000000c002300210000000000112019f00000d74011001c70000800d02000039000000020300003900000ddc04000041000000090500002933a8339e0000040f0000000101200190000032790000613d0000000801000029000000000101004b000032780000613d000000080100002900000000001004350000001601000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b000900000001001d000000070100002900000d580110009c000032810000213d00000d5c01000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000032790000613d000000000401043b00000d5d0140009c000032960000213d00000ceb0140009c0000000903000029000032ab0000213d000000000203041a000000000102004b0000000001000019000600000004001d000031c90000613d000500000002001d000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b00000005020000290000000001120019000000010110008a000000000101041a00000020011002700000000903000029000000060400002900000007020000290000000001210019000700000001001d00000d580110009c000032c00000213d000000000203041a000000000102004b000032050000613d000500000002001d000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000400200043d00000cef0320009c000000090400002900000006050000290000327b0000213d0000000503000029000000010730008a000000000101043b0000004003200039000000400030043f0000000001710019000000000101041a00000020031002700000002006200039000000000036043500000ceb011001970000000000120435000000000251004b000032c60000213d000000000151004b000500000006001d000032330000c13d000600000007001d000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b00000006020000290000000001210019000000070200002900000005040000290000325b0000013d000000400200043d00000cef0120009c0000327b0000213d0000004001200039000000400010043f00000000044204360000000701000029000900000004001d0000000000140435000000000403041a00000cf60140009c0000327b0000213d000600000002001d000500000004001d0000000101400039000000000013041b000000000030043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b00000005020000290000000001210019000000000201041a00000dda022001970000000603000029000000000303043300000ceb03300197000000000232019f000000000021041b000000000201041a00000ceb02200197000000090300002900000000030304330000002003300210000000000232019f000000000021041b0000000001000019000032620000013d000000400200043d00000cef0120009c0000327b0000213d0000004001200039000000400010043f00000000035204360000000701000029000600000003001d0000000000130435000000000304041a00000cf60130009c0000327b0000213d000400000002001d000300000003001d0000000101300039000000000014041b000000000040043500000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf7011001c7000080100200003933a833a30000040f0000000102200190000032790000613d000000000101043b00000003020000290000000001210019000000000201041a00000dda022001970000000403000029000000000303043300000ceb03300197000000000232019f000000000021041b0000000602000029000000000202043300000005040000290000002002200210000000000301041a00000ceb03300197000000000223019f000000000021041b000000000104043300000d5801100197000000400200043d000000200320003900000007040000290000000000430435000000000012043500000ceb01000041000000000300041400000ceb0430009c000000000301801900000ceb0420009c00000000010240190000004001100210000000c002300210000000000112019f00000d74011001c70000800d02000039000000020300003900000ddc04000041000000080500002933a8339e0000040f0000000101200190000032790000613d000000000001042d0000000001000019000033aa0001043000000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000000400100043d000000640210003900000ddf030000410000000000320435000000440210003900000de003000041000000000032043500000024021000390000002703000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000d61030000410000000000320435000000440210003900000d6203000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa00010430000000400100043d000000640210003900000ddd030000410000000000320435000000440210003900000dde03000041000000000032043500000024021000390000002603000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d54011001c7000033aa0001043000000d550100004100000000001004350000001101000039000000040010043f00000d5601000041000033aa00010430000000400100043d000000440210003900000ddb03000041000000000032043500000024021000390000001b03000039000000000032043500000d4d02000041000000000021043500000004021000390000002003000039000000000032043500000ceb0200004100000ceb0310009c0000000001028019000000400110021000000d4e011001c7000033aa0001043000000cee0110019700000000001004350000001801000039000000200010043f00000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000d74011001c7000080100200003933a833a30000040f0000000102200190000032eb0000613d000000000201043b000000000102041a0000000103100039000000000032041b000000000001042d0000000001000019000033aa00010430000400000000000200000db40100004100000000001004390000000001000412000300000001001d00000004001004430000004001000039000000240010044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000db5011001c7000080050200003933a833a30000040f0000000102200190000033960000613d000000000101043b00000cee011001970000000002000410000200000002001d000000000112004b000033370000c13d00000db4010000410000000000100439000000030100002900000004001004430000002001000039000000240010044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000db5011001c7000080050200003933a833a30000040f0000000102200190000033960000613d000000000101043b000400000001001d00000cf801000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000033960000613d000000000101043b0000000402000029000000000121004b000033370000c13d00000db401000041000000000010043900000003010000290000000400100443000000240000044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000db5011001c7000080050200003933a833a30000040f0000000102200190000033940000c13d000033960000013d000000400100043d000400000001001d000000200210003900000cfa01000041000100000002001d000000000012043500000db4010000410000000000100439000000030100002900000004001004430000006001000039000000240010044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000db5011001c7000080050200003933a833a30000040f0000000102200190000033960000613d000000000101043b00000004020000290000004002200039000000000012043500000db4010000410000000000100439000000030100002900000004001004430000008001000039000000240010044300000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000db5011001c7000080050200003933a833a30000040f0000000102200190000033960000613d000000000101043b00000004020000290000006002200039000000000012043500000cf801000041000000000010043900000ceb01000041000000000200041400000ceb0320009c0000000001024019000000c00110021000000cf9011001c70000800b0200003933a833a30000040f0000000102200190000033960000613d000000000101043b0000000404000029000000a0024000390000000203000029000000000032043500000080024000390000000000120435000000a001000039000000000014043500000dec0140009c000033980000813d0000000403000029000000c001300039000000400010043f00000ceb01000041000000010400002900000ceb0240009c000000000201001900000000020440190000004002200210000000000303043300000ceb0430009c00000000030180190000006003300210000000000223019f000000000300041400000ceb0430009c0000000001034019000000c001100210000000000121019f00000cf4011001c7000080100200003933a833a30000040f0000000102200190000033960000613d000000000101043b000000000001042d0000000001000019000033aa0001043000000d550100004100000000001004350000004101000039000000040010043f00000d5601000041000033aa00010430000033a1002104210000000102000039000000000001042d0000000002000019000000000001042d000033a6002104230000000102000039000000000001042d0000000002000019000000000001042d000033a800000432000033a90001042e000033aa00010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000100000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffbf566f746520457363726f77204b4f49000000000000000000000000000000000076654b4f490000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0000000000000000000000000000000000000000000000000ffffffffffffffff02000000000000000000000000000000000000200000000000000000000000009a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b02000002000000000000000000000000000000040000000000000000000000008b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f000000000000000000000000000000000000000000000000ffffffffffffff3f00000002000000000000000000000000000002000000010000000000000000000000000000000000000000000000000000000000000000000000000078229c3500000000000000000000000000000000000000000000000000000000b1548afb00000000000000000000000000000000000000000000000000000000e30c397700000000000000000000000000000000000000000000000000000000ebd5027e00000000000000000000000000000000000000000000000000000000f2fde38a00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000f8764cec00000000000000000000000000000000000000000000000000000000ebd5027f00000000000000000000000000000000000000000000000000000000efdd1eea00000000000000000000000000000000000000000000000000000000e30c397800000000000000000000000000000000000000000000000000000000e7a324dc00000000000000000000000000000000000000000000000000000000e985e9c500000000000000000000000000000000000000000000000000000000b88d4fdd00000000000000000000000000000000000000000000000000000000c1d5a61100000000000000000000000000000000000000000000000000000000c1d5a61200000000000000000000000000000000000000000000000000000000c87b56dd00000000000000000000000000000000000000000000000000000000b88d4fde00000000000000000000000000000000000000000000000000000000bc57615a00000000000000000000000000000000000000000000000000000000b1548afc00000000000000000000000000000000000000000000000000000000b20b10d100000000000000000000000000000000000000000000000000000000b6232164000000000000000000000000000000000000000000000000000000008e539e8b0000000000000000000000000000000000000000000000000000000095d89b40000000000000000000000000000000000000000000000000000000009b988345000000000000000000000000000000000000000000000000000000009b98834600000000000000000000000000000000000000000000000000000000a22cb4650000000000000000000000000000000000000000000000000000000095d89b41000000000000000000000000000000000000000000000000000000009ab24eb0000000000000000000000000000000000000000000000000000000008e539e8c0000000000000000000000000000000000000000000000000000000091ddadf4000000000000000000000000000000000000000000000000000000009351d540000000000000000000000000000000000000000000000000000000007ecebdff0000000000000000000000000000000000000000000000000000000084b0196d0000000000000000000000000000000000000000000000000000000084b0196e000000000000000000000000000000000000000000000000000000008da5cb5b000000000000000000000000000000000000000000000000000000007ecebe0000000000000000000000000000000000000000000000000000000000843862ea0000000000000000000000000000000000000000000000000000000078229c360000000000000000000000000000000000000000000000000000000079ba5097000000000000000000000000000000000000000000000000000000007bfa4a34000000000000000000000000000000000000000000000000000000003644e514000000000000000000000000000000000000000000000000000000004f8406db0000000000000000000000000000000000000000000000000000000064b56bf00000000000000000000000000000000000000000000000000000000070a082300000000000000000000000000000000000000000000000000000000070a0823100000000000000000000000000000000000000000000000000000000715018a60000000000000000000000000000000000000000000000000000000064b56bf10000000000000000000000000000000000000000000000000000000065a5d5f0000000000000000000000000000000000000000000000000000000004f8406dc000000000000000000000000000000000000000000000000000000004f99fecc000000000000000000000000000000000000000000000000000000006352211e0000000000000000000000000000000000000000000000000000000046d326b2000000000000000000000000000000000000000000000000000000004d4b1665000000000000000000000000000000000000000000000000000000004d4b1666000000000000000000000000000000000000000000000000000000004f6ccce70000000000000000000000000000000000000000000000000000000046d326b3000000000000000000000000000000000000000000000000000000004bf5d7e9000000000000000000000000000000000000000000000000000000003644e515000000000000000000000000000000000000000000000000000000003a46b1a80000000000000000000000000000000000000000000000000000000042842e0e000000000000000000000000000000000000000000000000000000001158050b0000000000000000000000000000000000000000000000000000000020606b6f00000000000000000000000000000000000000000000000000000000266cb42800000000000000000000000000000000000000000000000000000000266cb429000000000000000000000000000000000000000000000000000000002f745c590000000000000000000000000000000000000000000000000000000020606b700000000000000000000000000000000000000000000000000000000023b872dd000000000000000000000000000000000000000000000000000000001158050c0000000000000000000000000000000000000000000000000000000018160ddd000000000000000000000000000000000000000000000000000000001ac705b00000000000000000000000000000000000000000000000000000000008bbb8230000000000000000000000000000000000000000000000000000000008bbb82400000000000000000000000000000000000000000000000000000000095ea7b3000000000000000000000000000000000000000000000000000000000e7a3b880000000000000000000000000000000000000000000000000000000001ffc9a70000000000000000000000000000000000000000000000000000000006fdde0300000000000000000000000000000000000000000000000000000000081812fc0000000000000000000000000000000000000000000000000000000000093a8000000000000000000000000000000000000000200000000000000000000000004f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657208c379a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000038d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270077de7a3d03330f203f7ba626775e6fdedbd28274c4e65f51c0e702342bb388920000000000000000000000000000000000000000000000000000000001dfe20056414c49445f4f574e455200000000000000000000000000000000000000000076654b4f493a3a736574436f6e76657273696f6e436f6e74726163743a20494e00000000000000000000000000000000000000840000000000000000000000004e487b71000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db04c49445f4f574e4552000000000000000000000000000000000000000000000076654b4f493a3a6368616e67654d6574616461746150726f78793a20494e5641796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d955391320000000000000000000000000000000000000000000000000000ffffffffffff0000000000000000000000000000000000000000000000000001000000000000455f4c4f4f4b555000000000000000000000000000000000000000000000000076654b4f493a3a67657450617374546f74616c537570706c793a204655545552382062697473000000000000000000000000000000000000000000000000000053616665436173743a2076616c756520646f65736e27742066697420696e20346e6577206f776e657200000000000000000000000000000000000000000000004f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865200000000000000000000000000000000000000000000000000000000003bfc4007574206f6620626f756e64730000000000000000000000000000000000000000455243373231456e756d657261626c653a20676c6f62616c20696e646578206fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7ec56ab61150eaef6ee44ce42808c2056b7ccfd8ffa319b09a34abc8c721b9f208a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19bffffffff000000000000000000000000000000000000000000000000000000005b5e139f0000000000000000000000000000000000000000000000000000000080ac58cd000000000000000000000000000000000000000000000000000000004906490600000000000000000000000000000000000000000000000000000000780e9d630000000000000000000000000000000000000000000000000000000001ffc9a7000000000000000000000000000000000000000000000000000000000200000200000000000000000000000000000000000000000000000000000000545f43414c4c000000000000000000000000000000000000000000000000000076654b4f493a3a5265656e7472616e637947756172643a205245454e5452414e020000000000000000000000000000000000004000000000000000000000000076654b4f493a3a64656c65676174653a20494e56414c49445f4f574e455200004552433732313a20696e76616c696420746f6b656e204944000000000000000072000000000000000000000000000000000000000000000000000000000000004552433732313a20617070726f76616c20746f2063757272656e74206f776e65000000000000000000000000000000000000000000000000ffffffffffffffa0000000000000000000000000000000000000000000000000ffffffffffffffc0000000000000000000000000000000000000000000000000ffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffff9f76654b4f493a3a52656465656d3a20494e56414c49445f4f574e4552000000005f54494d4500000000000000000000000000000000000000000000000000000076654b4f493a3a52656465656d3a20494e53554646494349454e545f4c4f434ba9059cbb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000f15e8dbe6045728e48cc3afc6bf895b6ba5e25ab50b4963df96bdb1faf3d1be376654b4f493a3a52656465656d546f3a204641494c45445f5452414e5346455276654b4f493a3a52656465656d3a20494e56414c49445f41444452455353000070a082310000000000000000000000000000000000000000000000000000000023b872dd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093a7f0000000000000000000000000000000000000000000000000000000003bfc4010000000000000000000000000000000000000000000000000000000001dfe1ff02000000000000000000000000000000000000600000000000000000000000007ffcb823d8e837de0a296e22ad8f66b30396f3841f80b30079d0d7a862a8c8445f4d494e5445440000000000000000000000000000000000000000000000000076654b4f493a3a4c6f636b3a20494e53554646494349454e545f544f4b454e534d4500000000000000000000000000000000000000000000000000000000000076654b4f493a3a74696d65546f546f6b656e733a204f5645525f4d41585f5449494d45000000000000000000000000000000000000000000000000000000000076654b4f493a3a74696d65546f546f6b656e733a20554e4445525f4d494e5f5476654b4f493a3a4c6f636b3a204641494c45445f5452414e5346455246524f4d450000000000000000000000000000000000000000000000000000000000000076654b4f493a3a4c6f636b3a20494e53554646494349454e545f42414c414e437fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a102000000000000000000000000000000000000010000000000000000000000001901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f00000000000000000000000000000000000000800000000000000000000000004552524f5200000000000000000000000000000000000000000000000000000076654b4f493a3a64656c656761746542795369673a204d414c4c4541424c455f757000000000000000000000000000000000000000000000000000000000000076654b4f493a3a67657450617374566f7465733a20667574757265206c6f6f6b4552433230566f7465733a2062726f6b656e20636c6f636b206d6f64650000006d6f64653d74696d657374616d702666726f6d3d64656661756c74000000000074206f6620626f756e6473000000000000000000000000000000000000000000455243373231456e756d657261626c653a206f776e657220696e646578206f756c6964206f776e657200000000000000000000000000000000000000000000004552433732313a2061646472657373207a65726f206973206e6f742061207661524f5645445f4f574e455200000000000000000000000000000000000000000076654b4f493a3a496e6372656173654c6f636b54696d653a204e4f545f41505035e409d9dfc51d75a0f4c4567460e77653f289526d9b3bdd44fc73c31515dc114349454e545f4c4f434b5f414d4f554e5400000000000000000000000000000076654b4f493a3a496e6372656173654c6f636b54696d653a20494e53554646494349454e545f544f4b454e535f4d494e544544000000000000000000000000004349454e545f4c4f434b5f54494d45000000000000000000000000000000000076654b4f493a3a4d657267653a204e4f545f415050524f5645445f4f574e45520200000000000000000000000000000000000080000000000000000000000000af17d37851a3f70ff6c356223a30c6938092dd4fb21bf22c2d014d98f76f67df76654b4f493a3a4d657267653a2053414d455f544f4b454e494400000000000076654b4f493a3a4c6f636b546f41646d696e3a20496e76616c6964000000000046455246524f4d0000000000000000000000000000000000000000000000000076654b4f493a3a4c6f636b546f41646d696e3a204641494c45445f5452414e535f42414c414e434500000000000000000000000000000000000000000000000076654b4f493a3a4c6f636b546f41646d696e3a20494e53554646494349454e54310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e0200000200000000000000000000000000000044000000000000000000000000b3512b0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acec2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b000000000000000000000000000000000000000000000000ffffffffffffffdf0f0000000000000000000000000000000000000000000000000000000000000017307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c314552433732313a20617070726f766520746f2063616c6c65720000000000000076654b4f493a3a73706c69743a204e4f545f415050524f5645445f4f574e45524e5400000000000000000000000000000000000000000000000000000000000076654b4f493a3a73706c69743a20494e56414c49445f53504c49545f414d4f5501ae35e8e5e47510f9a842e1ae697b754851c87bf051cb053aad58d896d4b34e00000000000000000000000000000000000000400000000000000000000000004e545f5a45524f00000000000000000000000000000000000000000000000000cdd180a3000000000000000000000000000000000000000000000000000000006b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000004552433732313a20617070726f76652063616c6c6572206973206e6f7420746f72206f7220617070726f766564000000000000000000000000000000000000004552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6563656976657220696d706c656d656e74657200000000000000000000000000004552433732313a207472616e7366657220746f206e6f6e2045524337323152656f776e65720000000000000000000000000000000000000000000000000000004552433732313a207472616e736665722066726f6d20696e636f727265637420ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef72657373000000000000000000000000000000000000000000000000000000004552433732313a207472616e7366657220746f20746865207a65726f206164648c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9251806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000150b7a020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffe04552433732313a20746f6b656e20616c7265616479206d696e7465640000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000c624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c14c624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c15ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000436865636b706f696e743a2064656372656173696e67206b6579730000000000dec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724322062697473000000000000000000000000000000000000000000000000000053616665436173743a2076616c756520646f65736e27742066697420696e2033323420626974730000000000000000000000000000000000000000000000000053616665436173743a2076616c756520646f65736e27742066697420696e20324552433732313a206d696e7420746f20746865207a65726f2061646472657373df6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c600000000000000000000000000000000ffffffffffffffffffffffffffffffff4e4552000000000000000000000000000000000000000000000000000000000076654b4f493a3a64656c656761746542795369673a20494e56414c49445f4f57445245535300000000000000000000000000000000000000000000000000000076654b4f493a3a64656c656761746542795369673a20494e56414c49445f41444e4345000000000000000000000000000000000000000000000000000000000076654b4f493a3a64656c656761746542795369673a20494e56414c49445f4e4f76654b4f493a3a64656c656761746542795369673a2045585049524544000000f908e5f76d903c5b99dcf1f1dbd0b8f85f630cba1c80a66f8d5090ba202d6f63000000000000000000000000000000000000000000000000ffffffffffffff40000000000000000000000000000000000000000000000000000000000000000074eb04a967a8602246048d85733d09ac4206387d4e65f2710e7a501b53a6fd60
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a995ad25ce5eb76972ab356168f5e1d9257e4d05000000000000000000000000d38ebb608da8b4a9e75bb5a77dcf437ad423938c
-----Decoded View---------------
Arg [0] : _koiToken (address): 0xa995ad25Ce5eB76972ab356168f5e1D9257E4d05
Arg [1] : _metadata (address): 0xD38Ebb608dA8b4a9E75Bb5A77dCf437AD423938c
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a995ad25ce5eb76972ab356168f5e1d9257e4d05
Arg [1] : 000000000000000000000000d38ebb608da8b4a9e75bb5a77dcf437ad423938c
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.