Token ArbiPunks
Overview ERC-721
Total Supply:
10,001 APUNKS
Holders:
2,234 addresses
Contract:
Balance
178 APUNKS
[ Download CSV Export ]
[ Download CSV Export ]
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Nfts
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at Arbiscan.io on 2021-09-13 */ // Sources flattened with hardhat v2.6.0 https://hardhat.org // File contracts/erc721.sol // SPDX-License-Identifier: MIT pragma solidity 0.8.4; /** * @dev ERC-721 non-fungible token standard. * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md. */ interface ERC721 { /** * @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are * created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any * number of NFTs may be created and assigned without emitting Transfer. At the time of any * transfer, the approved address for that NFT (if any) is reset to none. */ event Transfer( address indexed _from, address indexed _to, uint256 indexed _tokenId ); /** * @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero * address indicates there is no approved address. When a Transfer event emits, this also * indicates that the approved address for that NFT (if any) is reset to none. */ event Approval( address indexed _owner, address indexed _approved, uint256 indexed _tokenId ); /** * @dev This emits when an operator is enabled or disabled for an owner. The operator can manage * all NFTs of the owner. */ event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved ); /** * @notice Throws unless `msg.sender` is the current owner, an authorized operator, or the * approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is * the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this * function checks if `_to` is a smart contract (code size > 0). If so, it calls * `onERC721Received` on `_to` and throws if the return value is not * `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`. * @dev Transfers the ownership of an NFT from one address to another address. This function can * be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes calldata _data ) external; /** * @notice This works identically to the other function with an extra data parameter, except this * function just sets data to "" * @dev Transfers the ownership of an NFT from one address to another address. This function can * be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId ) external; /** * @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else * they may be permanently lost. * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved * address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero * address. Throws if `_tokenId` is not a valid NFT. This function can be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function transferFrom( address _from, address _to, uint256 _tokenId ) external; /** * @notice The zero address indicates there is no approved address. Throws unless `msg.sender` is * the current NFT owner, or an authorized operator of the current owner. * @param _approved The new approved NFT controller. * @dev Set or reaffirm the approved address for an NFT. This function can be changed to payable. * @param _tokenId The NFT to approve. */ function approve(address _approved, uint256 _tokenId) external; /** * @notice The contract MUST allow multiple operators per owner. * @dev Enables or disables approval for a third party ("operator") to manage all of * `msg.sender`'s assets. It also emits the ApprovalForAll event. * @param _operator Address to add to the set of authorized operators. * @param _approved True if the operators is approved, false to revoke approval. */ function setApprovalForAll(address _operator, bool _approved) external; /** * @dev Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are * considered invalid, and this function throws for queries about the zero address. * @notice Count all NFTs assigned to an owner. * @param _owner Address for whom to query the balance. * @return Balance of _owner. */ function balanceOf(address _owner) external view returns (uint256); /** * @notice Find the owner of an NFT. * @dev Returns the address of the owner of the NFT. NFTs assigned to the zero address are * considered invalid, and queries about them do throw. * @param _tokenId The identifier for an NFT. * @return Address of _tokenId owner. */ function ownerOf(uint256 _tokenId) external view returns (address); /** * @notice Throws if `_tokenId` is not a valid NFT. * @dev Get the approved address for a single NFT. * @param _tokenId The NFT to find the approved address for. * @return Address that _tokenId is approved for. */ function getApproved(uint256 _tokenId) external view returns (address); /** * @notice Query if an address is an authorized operator for another address. * @dev Returns true if `_operator` is an approved operator for `_owner`, false otherwise. * @param _owner The address that owns the NFTs. * @param _operator The address that acts on behalf of the owner. * @return True if approved for all, false otherwise. */ function isApprovedForAll(address _owner, address _operator) external view returns (bool); } // File contracts/erc721-token-receiver.solpragma solidity 0.8.4; /** * @dev ERC-721 interface for accepting safe transfers. * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md. */ interface ERC721TokenReceiver { /** * @notice The contract address is always the message sender. A wallet/broker/auction application * MUST implement the wallet interface if it will accept safe transfers. * @dev Handle the receipt of a NFT. The ERC721 smart contract calls this function on the * recipient after a `transfer`. This function MAY throw to revert and reject the transfer. Return * of other than the magic value MUST result in the transaction being reverted. * Returns `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` unless throwing. * @param _operator The address which called `safeTransferFrom` function. * @param _from The address which previously owned the token. * @param _tokenId The NFT identifier which is being transferred. * @param _data Additional data with no specified format. * @return Returns `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. */ function onERC721Received( address _operator, address _from, uint256 _tokenId, bytes calldata _data ) external returns (bytes4); } // File contracts/erc165.solpragma solidity 0.8.4; /** * @dev A standard for detecting smart contract interfaces. * See: https://eips.ethereum.org/EIPS/eip-165. */ interface ERC165 { /** * @dev Checks if the smart contract includes a specific interface. * This function uses less than 30,000 gas. * @param _interfaceID The interface identifier, as specified in ERC-165. * @return True if _interfaceID is supported, false otherwise. */ function supportsInterface(bytes4 _interfaceID) external view returns (bool); } // File contracts/supports-interface.sol pragma solidity 0.8.4; /** * @dev Implementation of standard for detect smart contract interfaces. */ contract SupportsInterface is ERC165 { /** * @dev Mapping of supported intefraces. You must not set element 0xffffffff to true. */ mapping(bytes4 => bool) internal supportedInterfaces; /** * @dev Contract constructor. */ constructor() { supportedInterfaces[0x01ffc9a7] = true; // ERC165 } /** * @dev Function to check which interfaces are suported by this contract. * @param _interfaceID Id of the interface. * @return True if _interfaceID is supported, false otherwise. */ function supportsInterface(bytes4 _interfaceID) external view override returns (bool) { return supportedInterfaces[_interfaceID]; } } // File contracts/address-utils.sol pragma solidity 0.8.4; /** * @notice Based on: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol * Requires EIP-1052. * @dev Utility library of inline functions on addresses. */ library AddressUtils { /** * @dev Returns whether the target address is a contract. * @param _addr Address to check. * @return addressCheck True if _addr is a contract, false if not. */ function isContract(address _addr) internal view returns (bool addressCheck) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; assembly { codehash := extcodehash(_addr) } // solhint-disable-line addressCheck = (codehash != 0x0 && codehash != accountHash); } } // File contracts/nf-token.sol pragma solidity 0.8.4; /** * @dev Implementation of ERC-721 non-fungible token standard. */ contract NFToken is ERC721, SupportsInterface { using AddressUtils for address; /** * @dev List of revert message codes. Implementing dApp should handle showing the correct message. * Based on 0xcert framework error codes. */ string constant ZERO_ADDRESS = '003001'; string constant NOT_VALID_NFT = '003002'; string constant NOT_OWNER_OR_OPERATOR = '003003'; string constant NOT_OWNER_APPROVED_OR_OPERATOR = '003004'; string constant NOT_ABLE_TO_RECEIVE_NFT = '003005'; string constant NFT_ALREADY_EXISTS = '003006'; string constant NOT_OWNER = '003007'; string constant IS_OWNER = '003008'; /** * @dev Magic value of a smart contract that can receive NFT. * Equal to: bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")). */ bytes4 internal constant MAGIC_ON_ERC721_RECEIVED = 0x150b7a02; /** * @dev A mapping from NFT ID to the address that owns it. */ mapping(uint256 => address) internal idToOwner; /** * @dev Mapping from NFT ID to approved address. */ mapping(uint256 => address) internal idToApproval; /** * @dev Mapping from owner address to count of their tokens. */ mapping(address => uint256) private ownerToNFTokenCount; /** * @dev Mapping from owner address to mapping of operator addresses. */ mapping(address => mapping(address => bool)) internal ownerToOperators; /** * @dev Guarantees that the msg.sender is an owner or operator of the given NFT. * @param _tokenId ID of the NFT to validate. */ modifier canOperate(uint256 _tokenId) { address tokenOwner = idToOwner[_tokenId]; require( tokenOwner == msg.sender || ownerToOperators[tokenOwner][msg.sender], NOT_OWNER_OR_OPERATOR ); _; } /** * @dev Guarantees that the msg.sender is allowed to transfer NFT. * @param _tokenId ID of the NFT to transfer. */ modifier canTransfer(uint256 _tokenId) { address tokenOwner = idToOwner[_tokenId]; require( tokenOwner == msg.sender || idToApproval[_tokenId] == msg.sender || ownerToOperators[tokenOwner][msg.sender], NOT_OWNER_APPROVED_OR_OPERATOR ); _; } /** * @dev Guarantees that _tokenId is a valid Token. * @param _tokenId ID of the NFT to validate. */ modifier validNFToken(uint256 _tokenId) { require(idToOwner[_tokenId] != address(0), NOT_VALID_NFT); _; } /** * @dev Contract constructor. */ constructor() { supportedInterfaces[0x80ac58cd] = true; // ERC721 } /** * @notice Throws unless `msg.sender` is the current owner, an authorized operator, or the * approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is * the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this * function checks if `_to` is a smart contract (code size > 0). If so, it calls * `onERC721Received` on `_to` and throws if the return value is not * `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`. * @dev Transfers the ownership of an NFT from one address to another address. This function can * be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes calldata _data ) external override { _safeTransferFrom(_from, _to, _tokenId, _data); } /** * @notice This works identically to the other function with an extra data parameter, except this * function just sets data to "". * @dev Transfers the ownership of an NFT from one address to another address. This function can * be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId ) external override { _safeTransferFrom(_from, _to, _tokenId, ''); } /** * @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else * they may be permanently lost. * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved * address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero * address. Throws if `_tokenId` is not a valid NFT. This function can be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function transferFrom( address _from, address _to, uint256 _tokenId ) external override canTransfer(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(tokenOwner == _from, NOT_OWNER); require(_to != address(0), ZERO_ADDRESS); _transfer(_to, _tokenId); } /** * @notice The zero address indicates there is no approved address. Throws unless `msg.sender` is * the current NFT owner, or an authorized operator of the current owner. * @dev Set or reaffirm the approved address for an NFT. This function can be changed to payable. * @param _approved Address to be approved for the given NFT ID. * @param _tokenId ID of the token to be approved. */ function approve(address _approved, uint256 _tokenId) external override canOperate(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(_approved != tokenOwner, IS_OWNER); idToApproval[_tokenId] = _approved; emit Approval(tokenOwner, _approved, _tokenId); } /** * @notice This works even if sender doesn't own any tokens at the time. * @dev Enables or disables approval for a third party ("operator") to manage all of * `msg.sender`'s assets. It also emits the ApprovalForAll event. * @param _operator Address to add to the set of authorized operators. * @param _approved True if the operators is approved, false to revoke approval. */ function setApprovalForAll(address _operator, bool _approved) external override { ownerToOperators[msg.sender][_operator] = _approved; emit ApprovalForAll(msg.sender, _operator, _approved); } /** * @dev Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are * considered invalid, and this function throws for queries about the zero address. * @param _owner Address for whom to query the balance. * @return Balance of _owner. */ function balanceOf(address _owner) external view override returns (uint256) { require(_owner != address(0), ZERO_ADDRESS); return _getOwnerNFTCount(_owner); } /** * @dev Returns the address of the owner of the NFT. NFTs assigned to the zero address are * considered invalid, and queries about them do throw. * @param _tokenId The identifier for an NFT. * @return _owner Address of _tokenId owner. */ function ownerOf(uint256 _tokenId) external view override returns (address _owner) { _owner = idToOwner[_tokenId]; require(_owner != address(0), NOT_VALID_NFT); } /** * @notice Throws if `_tokenId` is not a valid NFT. * @dev Get the approved address for a single NFT. * @param _tokenId ID of the NFT to query the approval of. * @return Address that _tokenId is approved for. */ function getApproved(uint256 _tokenId) external view override validNFToken(_tokenId) returns (address) { return idToApproval[_tokenId]; } /** * @dev Checks if `_operator` is an approved operator for `_owner`. * @param _owner The address that owns the NFTs. * @param _operator The address that acts on behalf of the owner. * @return True if approved for all, false otherwise. */ function isApprovedForAll(address _owner, address _operator) external view override returns (bool) { return ownerToOperators[_owner][_operator]; } /** * @notice Does NO checks. * @dev Actually performs the transfer. * @param _to Address of a new owner. * @param _tokenId The NFT that is being transferred. */ function _transfer(address _to, uint256 _tokenId) internal { address from = idToOwner[_tokenId]; _clearApproval(_tokenId); _removeNFToken(from, _tokenId); _addNFToken(_to, _tokenId); emit Transfer(from, _to, _tokenId); } /** * @notice This is an internal function which should be called from user-implemented external * mint function. Its purpose is to show and properly initialize data structures when using this * implementation. * @dev Mints a new NFT. * @param _to The address that will own the minted NFT. * @param _tokenId of the NFT to be minted by the msg.sender. */ function _mint(address _to, uint256 _tokenId) internal virtual { require(_to != address(0), ZERO_ADDRESS); require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS); _addNFToken(_to, _tokenId); emit Transfer(address(0), _to, _tokenId); } /** * @notice This is an internal function which should be called from user-implemented external burn * function. Its purpose is to show and properly initialize data structures when using this * implementation. Also, note that this burn implementation allows the minter to re-mint a burned * NFT. * @dev Burns a NFT. * @param _tokenId ID of the NFT to be burned. */ function _burn(uint256 _tokenId) internal virtual validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; _clearApproval(_tokenId); _removeNFToken(tokenOwner, _tokenId); emit Transfer(tokenOwner, address(0), _tokenId); } /** * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @dev Removes a NFT from owner. * @param _from Address from which we want to remove the NFT. * @param _tokenId Which NFT we want to remove. */ function _removeNFToken(address _from, uint256 _tokenId) internal virtual { require(idToOwner[_tokenId] == _from, NOT_OWNER); ownerToNFTokenCount[_from] -= 1; delete idToOwner[_tokenId]; } /** * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @dev Assigns a new NFT to owner. * @param _to Address to which we want to add the NFT. * @param _tokenId Which NFT we want to add. */ function _addNFToken(address _to, uint256 _tokenId) internal virtual { require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS); idToOwner[_tokenId] = _to; ownerToNFTokenCount[_to] += 1; } /** * @dev Helper function that gets NFT count of owner. This is needed for overriding in enumerable * extension to remove double storage (gas optimization) of owner NFT count. * @param _owner Address for whom to query the count. * @return Number of _owner NFTs. */ function _getOwnerNFTCount(address _owner) internal view virtual returns (uint256) { return ownerToNFTokenCount[_owner]; } /** * @dev Actually perform the safeTransferFrom. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function _safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes memory _data ) private canTransfer(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(tokenOwner == _from, NOT_OWNER); require(_to != address(0), ZERO_ADDRESS); _transfer(_to, _tokenId); if (_to.isContract()) { bytes4 retval = ERC721TokenReceiver(_to).onERC721Received( msg.sender, _from, _tokenId, _data ); require( retval == MAGIC_ON_ERC721_RECEIVED, NOT_ABLE_TO_RECEIVE_NFT ); } } /** * @dev Clears the current approval of a given NFT ID. * @param _tokenId ID of the NFT to be transferred. */ function _clearApproval(uint256 _tokenId) private { delete idToApproval[_tokenId]; } } // File contracts/erc721-enumerable.solpragma solidity 0.8.4; /** * @dev Optional enumeration extension for ERC-721 non-fungible token standard. * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md. */ interface ERC721Enumerable { /** * @dev Returns a count of valid NFTs tracked by this contract, where each one of them has an * assigned and queryable owner not equal to the zero address. * @return Total supply of NFTs. */ function totalSupply() external view returns (uint256); /** * @dev Returns the token identifier for the `_index`th NFT. Sort order is not specified. * @param _index A counter less than `totalSupply()`. * @return Token id. */ function tokenByIndex(uint256 _index) external view returns (uint256); /** * @dev Returns the token identifier for the `_index`th NFT assigned to `_owner`. Sort order is * not specified. It throws if `_index` >= `balanceOf(_owner)` or if `_owner` is the zero address, * representing invalid NFTs. * @param _owner An address where we are interested in NFTs owned by them. * @param _index A counter less than `balanceOf(_owner)`. * @return Token id. */ function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); } // File contracts/nf-token-enumerable.solpragma solidity 0.8.4; /** * @dev Optional enumeration implementation for ERC-721 non-fungible token standard. */ contract NFTokenEnumerable is NFToken, ERC721Enumerable { /** * @dev List of revert message codes. Implementing dApp should handle showing the correct message. * Based on 0xcert framework error codes. */ string constant INVALID_INDEX = '005007'; /** * @dev Array of all NFT IDs. */ uint256[] internal tokens; /** * @dev Mapping from token ID to its index in global tokens array. */ mapping(uint256 => uint256) internal idToIndex; /** * @dev Mapping from owner to list of owned NFT IDs. */ mapping(address => uint256[]) internal ownerToIds; /** * @dev Mapping from NFT ID to its index in the owner tokens list. */ mapping(uint256 => uint256) internal idToOwnerIndex; /** * @dev Contract constructor. */ constructor() { supportedInterfaces[0x780e9d63] = true; // ERC721Enumerable } /** * @dev Returns the count of all existing NFTokens. * @return Total supply of NFTs. */ function totalSupply() external view override returns (uint256) { return tokens.length; } /** * @dev Returns NFT ID by its index. * @param _index A counter less than `totalSupply()`. * @return Token id. */ function tokenByIndex(uint256 _index) external view override returns (uint256) { require(_index < tokens.length, INVALID_INDEX); return tokens[_index]; } /** * @dev returns the n-th NFT ID from a list of owner's tokens. * @param _owner Token owner's address. * @param _index Index number representing n-th token in owner's list of tokens. * @return Token id. */ function tokenOfOwnerByIndex(address _owner, uint256 _index) external view override returns (uint256) { require(_index < ownerToIds[_owner].length, INVALID_INDEX); return ownerToIds[_owner][_index]; } /** * @notice This is an internal function which should be called from user-implemented external * mint function. Its purpose is to show and properly initialize data structures when using this * implementation. * @dev Mints a new NFT. * @param _to The address that will own the minted NFT. * @param _tokenId of the NFT to be minted by the msg.sender. */ function _mint(address _to, uint256 _tokenId) internal virtual override { super._mint(_to, _tokenId); tokens.push(_tokenId); idToIndex[_tokenId] = tokens.length - 1; } /** * @notice This is an internal function which should be called from user-implemented external * burn function. Its purpose is to show and properly initialize data structures when using this * implementation. Also, note that this burn implementation allows the minter to re-mint a burned * NFT. * @dev Burns a NFT. * @param _tokenId ID of the NFT to be burned. */ function _burn(uint256 _tokenId) internal virtual override { super._burn(_tokenId); uint256 tokenIndex = idToIndex[_tokenId]; uint256 lastTokenIndex = tokens.length - 1; uint256 lastToken = tokens[lastTokenIndex]; tokens[tokenIndex] = lastToken; tokens.pop(); // This wastes gas if you are burning the last token but saves a little gas if you are not. idToIndex[lastToken] = tokenIndex; idToIndex[_tokenId] = 0; } /** * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @dev Removes a NFT from an address. * @param _from Address from wich we want to remove the NFT. * @param _tokenId Which NFT we want to remove. */ function _removeNFToken(address _from, uint256 _tokenId) internal virtual override { require(idToOwner[_tokenId] == _from, NOT_OWNER); delete idToOwner[_tokenId]; uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId]; uint256 lastTokenIndex = ownerToIds[_from].length - 1; if (lastTokenIndex != tokenToRemoveIndex) { uint256 lastToken = ownerToIds[_from][lastTokenIndex]; ownerToIds[_from][tokenToRemoveIndex] = lastToken; idToOwnerIndex[lastToken] = tokenToRemoveIndex; } ownerToIds[_from].pop(); } /** * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @dev Assigns a new NFT to an address. * @param _to Address to wich we want to add the NFT. * @param _tokenId Which NFT we want to add. */ function _addNFToken(address _to, uint256 _tokenId) internal virtual override { require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS); idToOwner[_tokenId] = _to; ownerToIds[_to].push(_tokenId); idToOwnerIndex[_tokenId] = ownerToIds[_to].length - 1; } /** * @dev Helper function that gets NFT count of owner. This is needed for overriding in enumerable * extension to remove double storage(gas optimization) of owner NFT count. * @param _owner Address for whom to query the count. * @return Number of _owner NFTs. */ function _getOwnerNFTCount(address _owner) internal view virtual override returns (uint256) { return ownerToIds[_owner].length; } } // File contracts/erc721-metadata.sol pragma solidity 0.8.4; /** * @dev Optional metadata extension for ERC-721 non-fungible token standard. * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md. */ interface ERC721Metadata { /** * @dev Returns a descriptive name for a collection of NFTs in this contract. * @return _name Representing name. */ function name() external view returns (string memory _name); /** * @dev Returns a abbreviated name for a collection of NFTs in this contract. * @return _symbol Representing symbol. */ function symbol() external view returns (string memory _symbol); /** * @dev Returns a distinct Uniform Resource Identifier (URI) for a given asset. It Throws if * `_tokenId` is not a valid NFT. URIs are defined in RFC3986. The URI may point to a JSON file * that conforms to the "ERC721 Metadata JSON Schema". * @return URI of _tokenId. */ function tokenURI(uint256 _tokenId) external view returns (string memory); } // File contracts/nf-token-metadata.sol pragma solidity 0.8.4; /** * @dev Optional metadata implementation for ERC-721 non-fungible token standard. */ contract NFTokenMetadata is NFToken, ERC721Metadata { /** * @dev A descriptive name for a collection of NFTs. */ string internal nftName; /** * @dev An abbreviated name for NFTokens. */ string internal nftSymbol; /** * @dev Mapping from NFT ID to metadata uri. */ mapping(uint256 => string) internal idToUri; /** * @notice When implementing this contract don't forget to set nftName and nftSymbol. * @dev Contract constructor. */ constructor() { supportedInterfaces[0x5b5e139f] = true; // ERC721Metadata } /** * @dev Returns a descriptive name for a collection of NFTokens. * @return _name Representing name. */ function name() external view override returns (string memory _name) { _name = nftName; } /** * @dev Returns an abbreviated name for NFTokens. * @return _symbol Representing symbol. */ function symbol() external view override returns (string memory _symbol) { _symbol = nftSymbol; } /** * @dev A distinct URI (RFC 3986) for a given NFT. * @param _tokenId Id for which we want uri. * @return URI of _tokenId. */ function tokenURI(uint256 _tokenId) external view override validNFToken(_tokenId) returns (string memory) { return idToUri[_tokenId]; } /** * @notice This is an internal function which should be called from user-implemented external * burn function. Its purpose is to show and properly initialize data structures when using this * implementation. Also, note that this burn implementation allows the minter to re-mint a burned * NFT. * @dev Burns a NFT. * @param _tokenId ID of the NFT to be burned. */ function _burn(uint256 _tokenId) internal virtual override { super._burn(_tokenId); delete idToUri[_tokenId]; } /** * @notice This is an internal function which should be called from user-implemented external * function. Its purpose is to show and properly initialize data structures when using this * implementation. * @dev Set a distinct URI (RFC 3986) for a given NFT ID. * @param _tokenId Id for which we want URI. * @param _uri String representing RFC 3986 URI. */ function _setTokenUri(uint256 _tokenId, string memory _uri) internal validNFToken(_tokenId) { idToUri[_tokenId] = _uri; } } // File contracts/NFTokenMetadataEnumerable.sol pragma solidity 0.8.4; /** * @dev Optional metadata implementation for ERC-721 non-fungible token standard. */ abstract contract NFTokenEnumerableMetadata is NFToken, ERC721Metadata, ERC721Enumerable { /** * @dev A descriptive name for a collection of NFTs. */ string internal nftName; /** * @dev An abbreviated name for NFTokens. */ string internal nftSymbol; /** * @dev Mapping from NFT ID to metadata uri. */ mapping(uint256 => string) internal idToUri; /** * @dev List of revert message codes. Implementing dApp should handle showing the correct message. * Based on 0xcert framework error codes. */ string constant INVALID_INDEX = '005007'; /** * @dev Array of all NFT IDs. */ uint256[] internal tokens; /** * @dev Mapping from token ID to its index in global tokens array. */ mapping(uint256 => uint256) internal idToIndex; /** * @dev Mapping from owner to list of owned NFT IDs. */ mapping(address => uint256[]) internal ownerToIds; /** * @dev Mapping from NFT ID to its index in the owner tokens list. */ mapping(uint256 => uint256) internal idToOwnerIndex; /** * @notice When implementing this contract don't forget to set nftName and nftSymbol. * @dev Contract constructor. */ constructor() { supportedInterfaces[0x780e9d63] = true; // ERC721Enumerable supportedInterfaces[0x5b5e139f] = true; // ERC721Metadata } /** * @dev Returns a descriptive name for a collection of NFTokens. * @return _name Representing name. */ function name() external view override returns (string memory _name) { _name = nftName; } /** * @dev Returns an abbreviated name for NFTokens. * @return _symbol Representing symbol. */ function symbol() external view override returns (string memory _symbol) { _symbol = nftSymbol; } /** * @dev A distinct URI (RFC 3986) for a given NFT. * @param _tokenId Id for which we want uri. * @return URI of _tokenId. */ function tokenURI(uint256 _tokenId) external view override validNFToken(_tokenId) returns (string memory) { return idToUri[_tokenId]; } /** * @notice This is an internal function which should be called from user-implemented external * function. Its purpose is to show and properly initialize data structures when using this * implementation. * @dev Set a distinct URI (RFC 3986) for a given NFT ID. * @param _tokenId Id for which we want URI. * @param _uri String representing RFC 3986 URI. */ function _setTokenUri(uint256 _tokenId, string memory _uri) internal validNFToken(_tokenId) { idToUri[_tokenId] = _uri; } /** * @dev Returns the count of all existing NFTokens. * @return Total supply of NFTs. */ function totalSupply() external view override returns (uint256) { return tokens.length; } /** * @dev Returns NFT ID by its index. * @param _index A counter less than `totalSupply()`. * @return Token id. */ function tokenByIndex(uint256 _index) external view override returns (uint256) { require(_index < tokens.length, INVALID_INDEX); return tokens[_index]; } /** * @dev returns the n-th NFT ID from a list of owner's tokens. * @param _owner Token owner's address. * @param _index Index number representing n-th token in owner's list of tokens. * @return Token id. */ function tokenOfOwnerByIndex(address _owner, uint256 _index) external view override returns (uint256) { require(_index < ownerToIds[_owner].length, INVALID_INDEX); return ownerToIds[_owner][_index]; } /** * @notice This is an internal function which should be called from user-implemented external * mint function. Its purpose is to show and properly initialize data structures when using this * implementation. * @dev Mints a new NFT. * @param _to The address that will own the minted NFT. * @param _tokenId of the NFT to be minted by the msg.sender. */ function _mint(address _to, uint256 _tokenId) internal virtual override { super._mint(_to, _tokenId); tokens.push(_tokenId); idToIndex[_tokenId] = tokens.length - 1; } /** * @notice This is an internal function which should be called from user-implemented external * burn function. Its purpose is to show and properly initialize data structures when using this * implementation. Also, note that this burn implementation allows the minter to re-mint a burned * NFT. * @dev Burns a NFT. * @param _tokenId ID of the NFT to be burned. */ function _burn(uint256 _tokenId) internal virtual override { super._burn(_tokenId); uint256 tokenIndex = idToIndex[_tokenId]; uint256 lastTokenIndex = tokens.length - 1; uint256 lastToken = tokens[lastTokenIndex]; tokens[tokenIndex] = lastToken; tokens.pop(); delete idToUri[_tokenId]; // This wastes gas if you are burning the last token but saves a little gas if you are not. idToIndex[lastToken] = tokenIndex; idToIndex[_tokenId] = 0; } /** * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @dev Removes a NFT from an address. * @param _from Address from wich we want to remove the NFT. * @param _tokenId Which NFT we want to remove. */ function _removeNFToken(address _from, uint256 _tokenId) internal virtual override { require(idToOwner[_tokenId] == _from, NOT_OWNER); delete idToOwner[_tokenId]; uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId]; uint256 lastTokenIndex = ownerToIds[_from].length - 1; if (lastTokenIndex != tokenToRemoveIndex) { uint256 lastToken = ownerToIds[_from][lastTokenIndex]; ownerToIds[_from][tokenToRemoveIndex] = lastToken; idToOwnerIndex[lastToken] = tokenToRemoveIndex; } ownerToIds[_from].pop(); } /** * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @dev Assigns a new NFT to an address. * @param _to Address to wich we want to add the NFT. * @param _tokenId Which NFT we want to add. */ function _addNFToken(address _to, uint256 _tokenId) internal virtual override { require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS); idToOwner[_tokenId] = _to; ownerToIds[_to].push(_tokenId); idToOwnerIndex[_tokenId] = ownerToIds[_to].length - 1; } /** * @dev Helper function that gets NFT count of owner. This is needed for overriding in enumerable * extension to remove double storage(gas optimization) of owner NFT count. * @param _owner Address for whom to query the count. * @return Number of _owner NFTs. */ function _getOwnerNFTs(address _owner) internal view virtual returns (uint256[] memory) { return ownerToIds[_owner]; } /** * @dev Helper function that gets NFT count of owner. This is needed for overriding in enumerable * extension to remove double storage(gas optimization) of owner NFT count. * @param _owner Address for whom to query the count. * @return Number of _owner NFTs. */ function _getOwnerNFTCount(address _owner) internal view virtual override returns (uint256) { return ownerToIds[_owner].length; } } // File @openzeppelin/contracts/utils/[email protected] solidity 0.8.4; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/access/[email protected] solidity 0.8.4; /** * @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() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), 'Ownable: caller is not the owner'); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(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' ); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/utils/math/[email protected] pragma solidity 0.8.4; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File contracts/IReferral.sol pragma solidity 0.8.4; interface IReferral { /** * @dev Record referral. */ function recordReferral(address user, address referrer) external; /** * @dev Record referral share. */ function recordReferralShare(address referrer, uint256 share) external; /** * @dev Get the referrer address that referred the user. */ function getReferrer(address user) external view returns (address); } // File contracts/Nfts.sol pragma solidity 0.8.4; contract Nfts is NFTokenEnumerableMetadata, Ownable { using SafeMath for uint256; uint256 public price = 0.05 ether; // 0.05 eth uint256 public maxSupply = 10_000; string public baseUri = 'https://api.arbipunks.com/'; uint16 public refShare = 2000; // in basis points, so it's 20% IReferral public referralContract; event PriceUpdated(uint256 newPrice); event MaxSupplyUpdated(uint256 newMaxSupply); event BaseUriUpdated(string newBaseUri); event ReferralSharePaid( address indexed user, address indexed referrer, uint256 shareAmount ); constructor() { nftName = 'ArbiPunks'; nftSymbol = 'APUNKS'; } function mint(address _referrer) external payable { require(msg.value >= price, 'Amount is less than price'); require(maxSupply >= this.totalSupply(), 'Sold out'); uint256 count = msg.value / price; if ( msg.value > 0 && address(referralContract) != address(0) && _referrer != address(0) && _referrer != msg.sender ) { referralContract.recordReferral(msg.sender, _referrer); } for (uint256 i = 0; i < count; i++) { uint256 currentSupply = this.totalSupply(); uint256 tokenId = currentSupply; address to = msg.sender; super._mint(to, tokenId); super._setTokenUri( tokenId, string(abi.encodePacked(baseUri, toString(tokenId), '.json')) ); payReferral(msg.sender, msg.value); } } function getOwnerNFTs(address _owner) public view returns (uint256[] memory) { return super._getOwnerNFTs(_owner); } function withdraw() external onlyOwner { payable(msg.sender).transfer(address(this).balance); } function updatePrice(uint256 _newPrice) public onlyOwner { price = _newPrice; emit PriceUpdated(_newPrice); } function updateMaxSupply(uint256 _maxSupply) public onlyOwner { maxSupply = _maxSupply; emit MaxSupplyUpdated(_maxSupply); } function updateBaseUri(string memory _baseUri) public onlyOwner { baseUri = _baseUri; emit BaseUriUpdated(_baseUri); } // Update the referral contract address by the owner function setReferralAddress(IReferral _referralAddress) public onlyOwner { referralContract = _referralAddress; } // Update referral share rate by the owner function setRefShare(uint16 _refShare) public onlyOwner { refShare = _refShare; } // Pay referral share to the referrer who referred this user. function payReferral(address _to, uint256 _amount) internal { if (address(referralContract) != address(0) && refShare > 0) { address referrer = referralContract.getReferrer(_to); uint256 shareAmount = _amount.mul(refShare).div(10000); if (referrer != address(0) && shareAmount > 0) { payable(referrer).transfer(shareAmount); referralContract.recordReferralShare(referrer, shareAmount); emit ReferralSharePaid(_to, referrer, shareAmount); } } } function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT license // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return '0'; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } } // File @openzeppelin/contracts/token/ERC20/[email protected] solidity 0.8.4; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount ) external returns (bool); /** * @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 ); } // File @openzeppelin/contracts/utils/[email protected] solidity 0.8.4; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, 'Address: insufficient balance' ); (bool success, ) = recipient.call{value: amount}(''); require( success, 'Address: unable to send value, recipient may have reverted' ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, 'Address: low-level call with value failed' ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, 'Address: insufficient balance for call' ); require(isContract(target), 'Address: call to non-contract'); (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall( target, data, 'Address: low-level static call failed' ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), 'Address: static call to non-contract'); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev 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) { require(isContract(target), 'Address: delegate call to non-contract'); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] pragma solidity 0.8.4; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), 'SafeERC20: approve from non-zero to non-zero allowance' ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require( oldAllowance >= value, 'SafeERC20: decreased allowance below zero' ); uint256 newAllowance = oldAllowance - value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall( data, 'SafeERC20: low-level call failed' ); if (returndata.length > 0) { // Return data is optional require( abi.decode(returndata, (bool)), 'SafeERC20: ERC20 operation did not succeed' ); } } } // File contracts/Referral.solpragma solidity 0.8.4; contract Referral is IReferral, Ownable { using SafeERC20 for IERC20; mapping(address => bool) public operators; mapping(address => address) public referrers; // user address => referrer address mapping(address => uint256) public referralsCount; // referrer address => referrals count mapping(address => uint256) public totalReferralShares; // referrer address => total referral commissions event ReferralRecorded(address indexed user, address indexed referrer); event ReferralShareRecorded(address indexed referrer, uint256 commission); event OperatorUpdated(address indexed operator, bool indexed status); modifier onlyOperator() { require(operators[msg.sender], 'Operator: caller is not the operator'); _; } function recordReferral(address _user, address _referrer) public override onlyOperator { if ( _user != address(0) && _referrer != address(0) && _user != _referrer && referrers[_user] == address(0) ) { referrers[_user] = _referrer; referralsCount[_referrer] += 1; emit ReferralRecorded(_user, _referrer); } } function recordReferralShare(address _referrer, uint256 _share) public override onlyOperator { if (_referrer != address(0) && _share > 0) { totalReferralShares[_referrer] += _share; emit ReferralShareRecorded(_referrer, _share); } } // Get the referrer address that referred the user function getReferrer(address _user) public view override returns (address) { return referrers[_user]; } // Update the status of the operator function updateOperator(address _operator, bool _status) external onlyOwner { operators[_operator] = _status; emit OperatorUpdated(_operator, _status); } function transferTokens( IERC20 _token, uint256 _amount, address _to ) external onlyOwner { _token.safeTransfer(_to, _amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"string","name":"newBaseUri","type":"string"}],"name":"BaseUriUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxSupply","type":"uint256"}],"name":"MaxSupplyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"PriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"shareAmount","type":"uint256"}],"name":"ReferralSharePaid","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":[{"internalType":"address","name":"_approved","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":[],"name":"baseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"address","name":"_owner","type":"address"}],"name":"getOwnerNFTs","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":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_referrer","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refShare","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralContract","outputs":[{"internalType":"contract IReferral","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":"uint16","name":"_refShare","type":"uint16"}],"name":"setRefShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IReferral","name":"_referralAddress","type":"address"}],"name":"setReferralAddress","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":"_symbol","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":[{"internalType":"string","name":"_baseUri","type":"string"}],"name":"updateBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"updateMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"updatePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405266b1a2bc2ec50000600d55612710600e556040518060400160405280601a81526020017f68747470733a2f2f6170692e6172626970756e6b732e636f6d2f000000000000815250600f90805190602001906200006292919062000364565b506107d0601060006101000a81548161ffff021916908361ffff1602179055503480156200008f57600080fd5b5060016000806301ffc9a760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555060016000806380ac58cd60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff021916908315150217905550600160008063780e9d6360e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600080635b5e139f60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff021916908315150217905550620001f4620001e86200029660201b60201c565b6200029e60201b60201c565b6040518060400160405280600981526020017f4172626950756e6b730000000000000000000000000000000000000000000000815250600590805190602001906200024192919062000364565b506040518060400160405280600681526020017f4150554e4b530000000000000000000000000000000000000000000000000000815250600690805190602001906200028f92919062000364565b5062000479565b600033905090565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620003729062000414565b90600052602060002090601f016020900481019282620003965760008555620003e2565b82601f10620003b157805160ff1916838001178555620003e2565b82800160010185558215620003e2579182015b82811115620003e1578251825591602001919060010190620003c4565b5b509050620003f19190620003f5565b5090565b5b8082111562000410576000816000905550600101620003f6565b5090565b600060028204905060018216806200042d57607f821691505b602082108114156200044457620004436200044a565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b614a6b80620004896000396000f3fe6080604052600436106101e35760003560e01c8063715018a611610102578063a22cb46511610095578063d5abeb0111610064578063d5abeb01146106e3578063e985e9c51461070e578063f103b4331461074b578063f2fde38b14610774576101e3565b8063a22cb4651461062b578063b3caba5a14610654578063b88d4fde1461067d578063c87b56dd146106a6576101e3565b80638da5cb5b116100d15780638da5cb5b1461057f57806395d89b41146105aa5780639abc8320146105d5578063a035b1fe14610600576101e3565b8063715018a6146104d75780637dad19db146104ee5780638c017572146105195780638d6cc56d14610556576101e3565b80632f745c591161017a5780634f6ccce7116101495780634f6ccce7146104045780636352211e146104415780636a6278421461047e57806370a082311461049a576101e3565b80632f745c591461035e57806339f7e37f1461039b5780633ccfd60b146103c457806342842e0e146103db576101e3565b8063117d6507116101b6578063117d6507146102b657806318160ddd146102df5780631f4fc29c1461030a57806323b872dd14610335576101e3565b806301ffc9a7146101e857806306fdde0314610225578063081812fc14610250578063095ea7b31461028d575b600080fd5b3480156101f457600080fd5b5061020f600480360381019061020a9190613e28565b61079d565b60405161021c919061430a565b60405180910390f35b34801561023157600080fd5b5061023a610804565b6040516102479190614340565b60405180910390f35b34801561025c57600080fd5b5061027760048036038101906102729190613f0d565b610896565b604051610284919061422f565b60405180910390f35b34801561029957600080fd5b506102b460048036038101906102af9190613dec565b6109b1565b005b3480156102c257600080fd5b506102dd60048036038101906102d89190613ee4565b610d94565b005b3480156102eb57600080fd5b506102f4610e30565b60405161030191906143fd565b60405180910390f35b34801561031657600080fd5b5061031f610e3d565b60405161032c91906143e2565b60405180910390f35b34801561034157600080fd5b5061035c60048036038101906103579190613ce1565b610e51565b005b34801561036a57600080fd5b5061038560048036038101906103809190613dec565b6112a3565b60405161039291906143fd565b60405180910390f35b3480156103a757600080fd5b506103c260048036038101906103bd9190613ea3565b6113ec565b005b3480156103d057600080fd5b506103d96114b9565b005b3480156103e757600080fd5b5061040260048036038101906103fd9190613ce1565b61157e565b005b34801561041057600080fd5b5061042b60048036038101906104269190613f0d565b61159e565b60405161043891906143fd565b60405180910390f35b34801561044d57600080fd5b5061046860048036038101906104639190613f0d565b61166c565b604051610475919061422f565b60405180910390f35b61049860048036038101906104939190613c53565b611752565b005b3480156104a657600080fd5b506104c160048036038101906104bc9190613c53565b611aca565b6040516104ce91906143fd565b60405180910390f35b3480156104e357600080fd5b506104ec611b84565b005b3480156104fa57600080fd5b50610503611c0c565b6040516105109190614325565b60405180910390f35b34801561052557600080fd5b50610540600480360381019061053b9190613c53565b611c32565b60405161054d91906142e8565b60405180910390f35b34801561056257600080fd5b5061057d60048036038101906105789190613f0d565b611c44565b005b34801561058b57600080fd5b50610594611d01565b6040516105a1919061422f565b60405180910390f35b3480156105b657600080fd5b506105bf611d2b565b6040516105cc9190614340565b60405180910390f35b3480156105e157600080fd5b506105ea611dbd565b6040516105f79190614340565b60405180910390f35b34801561060c57600080fd5b50610615611e4b565b60405161062291906143fd565b60405180910390f35b34801561063757600080fd5b50610652600480360381019061064d9190613db0565b611e51565b005b34801561066057600080fd5b5061067b60048036038101906106769190613e7a565b611f4e565b005b34801561068957600080fd5b506106a4600480360381019061069f9190613d30565b61200e565b005b3480156106b257600080fd5b506106cd60048036038101906106c89190613f0d565b612065565b6040516106da9190614340565b60405180910390f35b3480156106ef57600080fd5b506106f86121e8565b60405161070591906143fd565b60405180910390f35b34801561071a57600080fd5b5061073560048036038101906107309190613ca5565b6121ee565b604051610742919061430a565b60405180910390f35b34801561075757600080fd5b50610772600480360381019061076d9190613f0d565b612282565b005b34801561078057600080fd5b5061079b60048036038101906107969190613c53565b61233f565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b6060600580546108139061470e565b80601f016020809104026020016040519081016040528092919081815260200182805461083f9061470e565b801561088c5780601f106108615761010080835404028352916020019161088c565b820191906000526020600020905b81548152906001019060200180831161086f57829003601f168201915b5050505050905090565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090610974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096b9190614340565b60405180910390fd5b506002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b8060006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610aaa5750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f303033303033000000000000000000000000000000000000000000000000000081525090610b21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b189190614340565b60405180910390fd5b5082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090610bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf59190614340565b60405180910390fd5b5060006001600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303038000000000000000000000000000000000000000000000000000081525090610cde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd59190614340565b60405180910390fd5b50856002600087815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050505050565b610d9c612437565b73ffffffffffffffffffffffffffffffffffffffff16610dba611d01565b73ffffffffffffffffffffffffffffffffffffffff1614610e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0790614382565b60405180910390fd5b80601060006101000a81548161ffff021916908361ffff16021790555050565b6000600880549050905090565b601060009054906101000a900461ffff1681565b8060006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610f2257503373ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b80610fb35750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f30303330303400000000000000000000000000000000000000000000000000008152509061102a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110219190614340565b60405180910390fd5b5082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090611107576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110fe9190614340565b60405180910390fd5b5060006001600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f3030333030370000000000000000000000000000000000000000000000000000815250906111e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111dd9190614340565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f30303330303100000000000000000000000000000000000000000000000000008152509061128f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112869190614340565b60405180910390fd5b5061129a868661243f565b50505050505050565b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905082106040518060400160405280600681526020017f303035303037000000000000000000000000000000000000000000000000000081525090611361576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113589190614340565b60405180910390fd5b50600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106113d9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6113f4612437565b73ffffffffffffffffffffffffffffffffffffffff16611412611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611468576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145f90614382565b60405180910390fd5b80600f908051906020019061147e929190613a41565b507f24a9152dc695ecc801ad580886331ee12d7aac0fa2ae341a5ae3c2ccae36cb4f816040516114ae9190614340565b60405180910390a150565b6114c1612437565b73ffffffffffffffffffffffffffffffffffffffff166114df611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161152c90614382565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561157b573d6000803e3d6000fd5b50565b611599838383604051806020016040528060008152506124f4565b505050565b600060088054905082106040518060400160405280600681526020017f30303530303700000000000000000000000000000000000000000000000000008152509061161f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116169190614340565b60405180910390fd5b506008828154811061165a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001549050919050565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f30303330303200000000000000000000000000000000000000000000000000008152509061174c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117439190614340565b60405180910390fd5b50919050565b600d54341015611797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178e906143a2565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117dd57600080fd5b505afa1580156117f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118159190613f36565b600e541015611859576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611850906143c2565b60405180910390fd5b6000600d54346118699190614555565b90506000341180156118ca5750600073ffffffffffffffffffffffffffffffffffffffff16601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156119035750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561193b57503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156119d057601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630c7f7b6b33846040518363ffffffff1660e01b815260040161199d92919061424a565b600060405180830381600087803b1580156119b757600080fd5b505af11580156119cb573d6000803e3d6000fd5b505050505b60005b81811015611ac55760003073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a2357600080fd5b505afa158015611a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5b9190613f36565b905060008190506000339050611a718183612ac2565b611aa582600f611a8085612b22565b604051602001611a91929190614200565b604051602081830303815290604052612ccf565b611aaf3334612dd9565b5050508080611abd90614771565b9150506119d3565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090611b73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6a9190614340565b60405180910390fd5b50611b7d826130c4565b9050919050565b611b8c612437565b73ffffffffffffffffffffffffffffffffffffffff16611baa611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611c00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf790614382565b60405180910390fd5b611c0a6000613110565b565b601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060611c3d826131d6565b9050919050565b611c4c612437565b73ffffffffffffffffffffffffffffffffffffffff16611c6a611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611cc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb790614382565b60405180910390fd5b80600d819055507f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe081604051611cf691906143fd565b60405180910390a150565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060068054611d3a9061470e565b80601f0160208091040260200160405190810160405280929190818152602001828054611d669061470e565b8015611db35780601f10611d8857610100808354040283529160200191611db3565b820191906000526020600020905b815481529060010190602001808311611d9657829003601f168201915b5050505050905090565b600f8054611dca9061470e565b80601f0160208091040260200160405190810160405280929190818152602001828054611df69061470e565b8015611e435780601f10611e1857610100808354040283529160200191611e43565b820191906000526020600020905b815481529060010190602001808311611e2657829003601f168201915b505050505081565b600d5481565b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611f42919061430a565b60405180910390a35050565b611f56612437565b73ffffffffffffffffffffffffffffffffffffffff16611f74611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611fca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc190614382565b60405180910390fd5b80601060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61205e85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506124f4565b5050505050565b606081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090612143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213a9190614340565b60405180910390fd5b506007600084815260200190815260200160002080546121629061470e565b80601f016020809104026020016040519081016040528092919081815260200182805461218e9061470e565b80156121db5780601f106121b0576101008083540402835291602001916121db565b820191906000526020600020905b8154815290600101906020018083116121be57829003601f168201915b5050505050915050919050565b600e5481565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61228a612437565b73ffffffffffffffffffffffffffffffffffffffff166122a8611d01565b73ffffffffffffffffffffffffffffffffffffffff16146122fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f590614382565b60405180910390fd5b80600e819055507f7810bd47de260c3e9ee10061cf438099dd12256c79485f12f94dbccc981e806c8160405161233491906143fd565b60405180910390a150565b612347612437565b73ffffffffffffffffffffffffffffffffffffffff16612365611d01565b73ffffffffffffffffffffffffffffffffffffffff16146123bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b290614382565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561242b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242290614362565b60405180910390fd5b61243481613110565b50565b600033905090565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506124808261326d565b61248a81836132a6565b61249483836135df565b818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b8160006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806125c557503373ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b806126565750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f3030333030340000000000000000000000000000000000000000000000000000815250906126cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c49190614340565b60405180910390fd5b5083600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f3030333030320000000000000000000000000000000000000000000000000000815250906127aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a19190614340565b60405180910390fd5b5060006001600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303037000000000000000000000000000000000000000000000000000081525090612889576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128809190614340565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090612932576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129299190614340565b60405180910390fd5b5061293d878761243f565b61295c8773ffffffffffffffffffffffffffffffffffffffff166137dc565b15612ab85760008773ffffffffffffffffffffffffffffffffffffffff1663150b7a02338b8a8a6040518563ffffffff1660e01b81526004016129a29493929190614273565b602060405180830381600087803b1580156129bc57600080fd5b505af11580156129d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129f49190613e51565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146040518060400160405280600681526020017f303033303035000000000000000000000000000000000000000000000000000081525090612ab5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aac9190614340565b60405180910390fd5b50505b5050505050505050565b612acc8282613827565b60088190806001815401808255809150506001900390600052602060002001600090919091909150556001600880549050612b0791906145e0565b60096000838152602001908152602001600020819055505050565b60606000821415612b6a576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612cca565b600082905060005b60008214612b9c578080612b8590614771565b915050600a82612b959190614555565b9150612b72565b60008167ffffffffffffffff811115612bde577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612c105781602001600182028036833780820191505090505b5090505b60008514612cc357600182612c2991906145e0565b9150600a85612c3891906147ba565b6030612c4491906144ff565b60f81b818381518110612c80577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612cbc9190614555565b9450612c14565b8093505050505b919050565b81600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090612dab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612da29190614340565b60405180910390fd5b5081600760008581526020019081526020016000209080519060200190612dd3929190613a41565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff16601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614158015612e4c57506000601060009054906101000a900461ffff1661ffff16115b156130c0576000601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634a9fefc7846040518263ffffffff1660e01b8152600401612eae919061422f565b60206040518083038186803b158015612ec657600080fd5b505afa158015612eda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efe9190613c7c565b90506000612f3d612710612f2f601060009054906101000a900461ffff1661ffff1686613a1590919063ffffffff16565b613a2b90919063ffffffff16565b9050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015612f7c5750600081115b156130bd578173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015612fc7573d6000803e3d6000fd5b50601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630daf16ed83836040518363ffffffff1660e01b81526004016130259291906142bf565b600060405180830381600087803b15801561303f57600080fd5b505af1158015613053573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f3d7fe97a05338f5c0493489b396ff7334f8873465d8504b44641c554f3856f1c836040516130b491906143fd565b60405180910390a35b50505b5050565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561326157602002820191906000526020600020905b81548152602001906001019080831161324d575b50505050509050919050565b6002600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b8173ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f30303330303700000000000000000000000000000000000000000000000000008152509061337f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133769190614340565b60405180910390fd5b506001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600b600083815260200190815260200160002054905060006001600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061341f91906145e0565b905081811461354e576000600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106134a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208481548110613526577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555082600b600083815260200190815260200160002081905550505b600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806135c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f3030333030360000000000000000000000000000000000000000000000000000815250906136b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136b09190614340565b60405180910390fd5b50816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002001600090919091909150556001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490506137c191906145e0565b600b6000838152602001908152602001600020819055505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f91506000801b821415801561381e5750808214155b92505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f3030333030310000000000000000000000000000000000000000000000000000815250906138cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138c69190614340565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f3030333030360000000000000000000000000000000000000000000000000000815250906139aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139a19190614340565b60405180910390fd5b506139b582826135df565b808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60008183613a239190614586565b905092915050565b60008183613a399190614555565b905092915050565b828054613a4d9061470e565b90600052602060002090601f016020900481019282613a6f5760008555613ab6565b82601f10613a8857805160ff1916838001178555613ab6565b82800160010185558215613ab6579182015b82811115613ab5578251825591602001919060010190613a9a565b5b509050613ac39190613ac7565b5090565b5b80821115613ae0576000816000905550600101613ac8565b5090565b6000613af7613af28461443d565b614418565b905082815260208101848484011115613b0f57600080fd5b613b1a8482856146cc565b509392505050565b600081359050613b31816149ab565b92915050565b600081519050613b46816149ab565b92915050565b600081359050613b5b816149c2565b92915050565b600081359050613b70816149d9565b92915050565b600081519050613b85816149d9565b92915050565b60008083601f840112613b9d57600080fd5b8235905067ffffffffffffffff811115613bb657600080fd5b602083019150836001820283011115613bce57600080fd5b9250929050565b600081359050613be4816149f0565b92915050565b600082601f830112613bfb57600080fd5b8135613c0b848260208601613ae4565b91505092915050565b600081359050613c2381614a07565b92915050565b600081359050613c3881614a1e565b92915050565b600081519050613c4d81614a1e565b92915050565b600060208284031215613c6557600080fd5b6000613c7384828501613b22565b91505092915050565b600060208284031215613c8e57600080fd5b6000613c9c84828501613b37565b91505092915050565b60008060408385031215613cb857600080fd5b6000613cc685828601613b22565b9250506020613cd785828601613b22565b9150509250929050565b600080600060608486031215613cf657600080fd5b6000613d0486828701613b22565b9350506020613d1586828701613b22565b9250506040613d2686828701613c29565b9150509250925092565b600080600080600060808688031215613d4857600080fd5b6000613d5688828901613b22565b9550506020613d6788828901613b22565b9450506040613d7888828901613c29565b935050606086013567ffffffffffffffff811115613d9557600080fd5b613da188828901613b8b565b92509250509295509295909350565b60008060408385031215613dc357600080fd5b6000613dd185828601613b22565b9250506020613de285828601613b4c565b9150509250929050565b60008060408385031215613dff57600080fd5b6000613e0d85828601613b22565b9250506020613e1e85828601613c29565b9150509250929050565b600060208284031215613e3a57600080fd5b6000613e4884828501613b61565b91505092915050565b600060208284031215613e6357600080fd5b6000613e7184828501613b76565b91505092915050565b600060208284031215613e8c57600080fd5b6000613e9a84828501613bd5565b91505092915050565b600060208284031215613eb557600080fd5b600082013567ffffffffffffffff811115613ecf57600080fd5b613edb84828501613bea565b91505092915050565b600060208284031215613ef657600080fd5b6000613f0484828501613c14565b91505092915050565b600060208284031215613f1f57600080fd5b6000613f2d84828501613c29565b91505092915050565b600060208284031215613f4857600080fd5b6000613f5684828501613c3e565b91505092915050565b6000613f6b83836141e2565b60208301905092915050565b613f8081614614565b82525050565b6000613f9182614493565b613f9b81856144c1565b9350613fa68361446e565b8060005b83811015613fd7578151613fbe8882613f5f565b9750613fc9836144b4565b925050600181019050613faa565b5085935050505092915050565b613fed81614626565b82525050565b6000613ffe8261449e565b61400881856144d2565b93506140188185602086016146db565b614021816148a7565b840191505092915050565b614035816146a8565b82525050565b6000614046826144a9565b61405081856144e3565b93506140608185602086016146db565b614069816148a7565b840191505092915050565b600061407f826144a9565b61408981856144f4565b93506140998185602086016146db565b80840191505092915050565b600081546140b28161470e565b6140bc81866144f4565b945060018216600081146140d757600181146140e85761411b565b60ff1983168652818601935061411b565b6140f18561447e565b60005b83811015614113578154818901526001820191506020810190506140f4565b838801955050505b50505092915050565b60006141316026836144e3565b915061413c826148b8565b604082019050919050565b60006141546005836144f4565b915061415f82614907565b600582019050919050565b60006141776020836144e3565b915061418282614930565b602082019050919050565b600061419a6019836144e3565b91506141a582614959565b602082019050919050565b60006141bd6008836144e3565b91506141c882614982565b602082019050919050565b6141dc81614670565b82525050565b6141eb8161469e565b82525050565b6141fa8161469e565b82525050565b600061420c82856140a5565b91506142188284614074565b915061422382614147565b91508190509392505050565b60006020820190506142446000830184613f77565b92915050565b600060408201905061425f6000830185613f77565b61426c6020830184613f77565b9392505050565b60006080820190506142886000830187613f77565b6142956020830186613f77565b6142a260408301856141f1565b81810360608301526142b48184613ff3565b905095945050505050565b60006040820190506142d46000830185613f77565b6142e160208301846141f1565b9392505050565b600060208201905081810360008301526143028184613f86565b905092915050565b600060208201905061431f6000830184613fe4565b92915050565b600060208201905061433a600083018461402c565b92915050565b6000602082019050818103600083015261435a818461403b565b905092915050565b6000602082019050818103600083015261437b81614124565b9050919050565b6000602082019050818103600083015261439b8161416a565b9050919050565b600060208201905081810360008301526143bb8161418d565b9050919050565b600060208201905081810360008301526143db816141b0565b9050919050565b60006020820190506143f760008301846141d3565b92915050565b600060208201905061441260008301846141f1565b92915050565b6000614422614433565b905061442e8282614740565b919050565b6000604051905090565b600067ffffffffffffffff82111561445857614457614878565b5b614461826148a7565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061450a8261469e565b91506145158361469e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561454a576145496147eb565b5b828201905092915050565b60006145608261469e565b915061456b8361469e565b92508261457b5761457a61481a565b5b828204905092915050565b60006145918261469e565b915061459c8361469e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145d5576145d46147eb565b5b828202905092915050565b60006145eb8261469e565b91506145f68361469e565b925082821015614609576146086147eb565b5b828203905092915050565b600061461f8261467e565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600061466982614614565b9050919050565b600061ffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006146b3826146ba565b9050919050565b60006146c58261467e565b9050919050565b82818337600083830152505050565b60005b838110156146f95780820151818401526020810190506146de565b83811115614708576000848401525b50505050565b6000600282049050600182168061472657607f821691505b6020821081141561473a57614739614849565b5b50919050565b614749826148a7565b810181811067ffffffffffffffff8211171561476857614767614878565b5b80604052505050565b600061477c8261469e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156147af576147ae6147eb565b5b600182019050919050565b60006147c58261469e565b91506147d08361469e565b9250826147e0576147df61481a565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f416d6f756e74206973206c657373207468616e20707269636500000000000000600082015250565b7f536f6c64206f7574000000000000000000000000000000000000000000000000600082015250565b6149b481614614565b81146149bf57600080fd5b50565b6149cb81614626565b81146149d657600080fd5b50565b6149e281614632565b81146149ed57600080fd5b50565b6149f98161465e565b8114614a0457600080fd5b50565b614a1081614670565b8114614a1b57600080fd5b50565b614a278161469e565b8114614a3257600080fd5b5056fea264697066735822122029a71587885fc4917d56b25cc11e39f6b22e88783bb02da93fd6aeb88c93d5f564736f6c63430008040033
Deployed Bytecode
0x6080604052600436106101e35760003560e01c8063715018a611610102578063a22cb46511610095578063d5abeb0111610064578063d5abeb01146106e3578063e985e9c51461070e578063f103b4331461074b578063f2fde38b14610774576101e3565b8063a22cb4651461062b578063b3caba5a14610654578063b88d4fde1461067d578063c87b56dd146106a6576101e3565b80638da5cb5b116100d15780638da5cb5b1461057f57806395d89b41146105aa5780639abc8320146105d5578063a035b1fe14610600576101e3565b8063715018a6146104d75780637dad19db146104ee5780638c017572146105195780638d6cc56d14610556576101e3565b80632f745c591161017a5780634f6ccce7116101495780634f6ccce7146104045780636352211e146104415780636a6278421461047e57806370a082311461049a576101e3565b80632f745c591461035e57806339f7e37f1461039b5780633ccfd60b146103c457806342842e0e146103db576101e3565b8063117d6507116101b6578063117d6507146102b657806318160ddd146102df5780631f4fc29c1461030a57806323b872dd14610335576101e3565b806301ffc9a7146101e857806306fdde0314610225578063081812fc14610250578063095ea7b31461028d575b600080fd5b3480156101f457600080fd5b5061020f600480360381019061020a9190613e28565b61079d565b60405161021c919061430a565b60405180910390f35b34801561023157600080fd5b5061023a610804565b6040516102479190614340565b60405180910390f35b34801561025c57600080fd5b5061027760048036038101906102729190613f0d565b610896565b604051610284919061422f565b60405180910390f35b34801561029957600080fd5b506102b460048036038101906102af9190613dec565b6109b1565b005b3480156102c257600080fd5b506102dd60048036038101906102d89190613ee4565b610d94565b005b3480156102eb57600080fd5b506102f4610e30565b60405161030191906143fd565b60405180910390f35b34801561031657600080fd5b5061031f610e3d565b60405161032c91906143e2565b60405180910390f35b34801561034157600080fd5b5061035c60048036038101906103579190613ce1565b610e51565b005b34801561036a57600080fd5b5061038560048036038101906103809190613dec565b6112a3565b60405161039291906143fd565b60405180910390f35b3480156103a757600080fd5b506103c260048036038101906103bd9190613ea3565b6113ec565b005b3480156103d057600080fd5b506103d96114b9565b005b3480156103e757600080fd5b5061040260048036038101906103fd9190613ce1565b61157e565b005b34801561041057600080fd5b5061042b60048036038101906104269190613f0d565b61159e565b60405161043891906143fd565b60405180910390f35b34801561044d57600080fd5b5061046860048036038101906104639190613f0d565b61166c565b604051610475919061422f565b60405180910390f35b61049860048036038101906104939190613c53565b611752565b005b3480156104a657600080fd5b506104c160048036038101906104bc9190613c53565b611aca565b6040516104ce91906143fd565b60405180910390f35b3480156104e357600080fd5b506104ec611b84565b005b3480156104fa57600080fd5b50610503611c0c565b6040516105109190614325565b60405180910390f35b34801561052557600080fd5b50610540600480360381019061053b9190613c53565b611c32565b60405161054d91906142e8565b60405180910390f35b34801561056257600080fd5b5061057d60048036038101906105789190613f0d565b611c44565b005b34801561058b57600080fd5b50610594611d01565b6040516105a1919061422f565b60405180910390f35b3480156105b657600080fd5b506105bf611d2b565b6040516105cc9190614340565b60405180910390f35b3480156105e157600080fd5b506105ea611dbd565b6040516105f79190614340565b60405180910390f35b34801561060c57600080fd5b50610615611e4b565b60405161062291906143fd565b60405180910390f35b34801561063757600080fd5b50610652600480360381019061064d9190613db0565b611e51565b005b34801561066057600080fd5b5061067b60048036038101906106769190613e7a565b611f4e565b005b34801561068957600080fd5b506106a4600480360381019061069f9190613d30565b61200e565b005b3480156106b257600080fd5b506106cd60048036038101906106c89190613f0d565b612065565b6040516106da9190614340565b60405180910390f35b3480156106ef57600080fd5b506106f86121e8565b60405161070591906143fd565b60405180910390f35b34801561071a57600080fd5b5061073560048036038101906107309190613ca5565b6121ee565b604051610742919061430a565b60405180910390f35b34801561075757600080fd5b50610772600480360381019061076d9190613f0d565b612282565b005b34801561078057600080fd5b5061079b60048036038101906107969190613c53565b61233f565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b6060600580546108139061470e565b80601f016020809104026020016040519081016040528092919081815260200182805461083f9061470e565b801561088c5780601f106108615761010080835404028352916020019161088c565b820191906000526020600020905b81548152906001019060200180831161086f57829003601f168201915b5050505050905090565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090610974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096b9190614340565b60405180910390fd5b506002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b8060006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610aaa5750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f303033303033000000000000000000000000000000000000000000000000000081525090610b21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b189190614340565b60405180910390fd5b5082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090610bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf59190614340565b60405180910390fd5b5060006001600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303038000000000000000000000000000000000000000000000000000081525090610cde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd59190614340565b60405180910390fd5b50856002600087815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050505050565b610d9c612437565b73ffffffffffffffffffffffffffffffffffffffff16610dba611d01565b73ffffffffffffffffffffffffffffffffffffffff1614610e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0790614382565b60405180910390fd5b80601060006101000a81548161ffff021916908361ffff16021790555050565b6000600880549050905090565b601060009054906101000a900461ffff1681565b8060006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610f2257503373ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b80610fb35750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f30303330303400000000000000000000000000000000000000000000000000008152509061102a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110219190614340565b60405180910390fd5b5082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090611107576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110fe9190614340565b60405180910390fd5b5060006001600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f3030333030370000000000000000000000000000000000000000000000000000815250906111e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111dd9190614340565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f30303330303100000000000000000000000000000000000000000000000000008152509061128f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112869190614340565b60405180910390fd5b5061129a868661243f565b50505050505050565b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905082106040518060400160405280600681526020017f303035303037000000000000000000000000000000000000000000000000000081525090611361576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113589190614340565b60405180910390fd5b50600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106113d9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6113f4612437565b73ffffffffffffffffffffffffffffffffffffffff16611412611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611468576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145f90614382565b60405180910390fd5b80600f908051906020019061147e929190613a41565b507f24a9152dc695ecc801ad580886331ee12d7aac0fa2ae341a5ae3c2ccae36cb4f816040516114ae9190614340565b60405180910390a150565b6114c1612437565b73ffffffffffffffffffffffffffffffffffffffff166114df611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161152c90614382565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505015801561157b573d6000803e3d6000fd5b50565b611599838383604051806020016040528060008152506124f4565b505050565b600060088054905082106040518060400160405280600681526020017f30303530303700000000000000000000000000000000000000000000000000008152509061161f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116169190614340565b60405180910390fd5b506008828154811061165a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001549050919050565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f30303330303200000000000000000000000000000000000000000000000000008152509061174c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117439190614340565b60405180910390fd5b50919050565b600d54341015611797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178e906143a2565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117dd57600080fd5b505afa1580156117f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118159190613f36565b600e541015611859576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611850906143c2565b60405180910390fd5b6000600d54346118699190614555565b90506000341180156118ca5750600073ffffffffffffffffffffffffffffffffffffffff16601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156119035750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561193b57503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156119d057601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630c7f7b6b33846040518363ffffffff1660e01b815260040161199d92919061424a565b600060405180830381600087803b1580156119b757600080fd5b505af11580156119cb573d6000803e3d6000fd5b505050505b60005b81811015611ac55760003073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a2357600080fd5b505afa158015611a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5b9190613f36565b905060008190506000339050611a718183612ac2565b611aa582600f611a8085612b22565b604051602001611a91929190614200565b604051602081830303815290604052612ccf565b611aaf3334612dd9565b5050508080611abd90614771565b9150506119d3565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090611b73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6a9190614340565b60405180910390fd5b50611b7d826130c4565b9050919050565b611b8c612437565b73ffffffffffffffffffffffffffffffffffffffff16611baa611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611c00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf790614382565b60405180910390fd5b611c0a6000613110565b565b601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060611c3d826131d6565b9050919050565b611c4c612437565b73ffffffffffffffffffffffffffffffffffffffff16611c6a611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611cc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cb790614382565b60405180910390fd5b80600d819055507f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe081604051611cf691906143fd565b60405180910390a150565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060068054611d3a9061470e565b80601f0160208091040260200160405190810160405280929190818152602001828054611d669061470e565b8015611db35780601f10611d8857610100808354040283529160200191611db3565b820191906000526020600020905b815481529060010190602001808311611d9657829003601f168201915b5050505050905090565b600f8054611dca9061470e565b80601f0160208091040260200160405190810160405280929190818152602001828054611df69061470e565b8015611e435780601f10611e1857610100808354040283529160200191611e43565b820191906000526020600020905b815481529060010190602001808311611e2657829003601f168201915b505050505081565b600d5481565b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611f42919061430a565b60405180910390a35050565b611f56612437565b73ffffffffffffffffffffffffffffffffffffffff16611f74611d01565b73ffffffffffffffffffffffffffffffffffffffff1614611fca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc190614382565b60405180910390fd5b80601060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61205e85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506124f4565b5050505050565b606081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090612143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213a9190614340565b60405180910390fd5b506007600084815260200190815260200160002080546121629061470e565b80601f016020809104026020016040519081016040528092919081815260200182805461218e9061470e565b80156121db5780601f106121b0576101008083540402835291602001916121db565b820191906000526020600020905b8154815290600101906020018083116121be57829003601f168201915b5050505050915050919050565b600e5481565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61228a612437565b73ffffffffffffffffffffffffffffffffffffffff166122a8611d01565b73ffffffffffffffffffffffffffffffffffffffff16146122fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f590614382565b60405180910390fd5b80600e819055507f7810bd47de260c3e9ee10061cf438099dd12256c79485f12f94dbccc981e806c8160405161233491906143fd565b60405180910390a150565b612347612437565b73ffffffffffffffffffffffffffffffffffffffff16612365611d01565b73ffffffffffffffffffffffffffffffffffffffff16146123bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b290614382565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561242b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242290614362565b60405180910390fd5b61243481613110565b50565b600033905090565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506124808261326d565b61248a81836132a6565b61249483836135df565b818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b8160006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806125c557503373ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b806126565750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f3030333030340000000000000000000000000000000000000000000000000000815250906126cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c49190614340565b60405180910390fd5b5083600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f3030333030320000000000000000000000000000000000000000000000000000815250906127aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a19190614340565b60405180910390fd5b5060006001600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303037000000000000000000000000000000000000000000000000000081525090612889576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128809190614340565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090612932576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129299190614340565b60405180910390fd5b5061293d878761243f565b61295c8773ffffffffffffffffffffffffffffffffffffffff166137dc565b15612ab85760008773ffffffffffffffffffffffffffffffffffffffff1663150b7a02338b8a8a6040518563ffffffff1660e01b81526004016129a29493929190614273565b602060405180830381600087803b1580156129bc57600080fd5b505af11580156129d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129f49190613e51565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146040518060400160405280600681526020017f303033303035000000000000000000000000000000000000000000000000000081525090612ab5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aac9190614340565b60405180910390fd5b50505b5050505050505050565b612acc8282613827565b60088190806001815401808255809150506001900390600052602060002001600090919091909150556001600880549050612b0791906145e0565b60096000838152602001908152602001600020819055505050565b60606000821415612b6a576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612cca565b600082905060005b60008214612b9c578080612b8590614771565b915050600a82612b959190614555565b9150612b72565b60008167ffffffffffffffff811115612bde577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612c105781602001600182028036833780820191505090505b5090505b60008514612cc357600182612c2991906145e0565b9150600a85612c3891906147ba565b6030612c4491906144ff565b60f81b818381518110612c80577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612cbc9190614555565b9450612c14565b8093505050505b919050565b81600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090612dab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612da29190614340565b60405180910390fd5b5081600760008581526020019081526020016000209080519060200190612dd3929190613a41565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff16601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614158015612e4c57506000601060009054906101000a900461ffff1661ffff16115b156130c0576000601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634a9fefc7846040518263ffffffff1660e01b8152600401612eae919061422f565b60206040518083038186803b158015612ec657600080fd5b505afa158015612eda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efe9190613c7c565b90506000612f3d612710612f2f601060009054906101000a900461ffff1661ffff1686613a1590919063ffffffff16565b613a2b90919063ffffffff16565b9050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015612f7c5750600081115b156130bd578173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015612fc7573d6000803e3d6000fd5b50601060029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630daf16ed83836040518363ffffffff1660e01b81526004016130259291906142bf565b600060405180830381600087803b15801561303f57600080fd5b505af1158015613053573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f3d7fe97a05338f5c0493489b396ff7334f8873465d8504b44641c554f3856f1c836040516130b491906143fd565b60405180910390a35b50505b5050565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561326157602002820191906000526020600020905b81548152602001906001019080831161324d575b50505050509050919050565b6002600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b8173ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f30303330303700000000000000000000000000000000000000000000000000008152509061337f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133769190614340565b60405180910390fd5b506001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600b600083815260200190815260200160002054905060006001600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061341f91906145e0565b905081811461354e576000600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106134a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208481548110613526577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555082600b600083815260200190815260200160002081905550505b600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806135c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f3030333030360000000000000000000000000000000000000000000000000000815250906136b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136b09190614340565b60405180910390fd5b50816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002001600090919091909150556001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490506137c191906145e0565b600b6000838152602001908152602001600020819055505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f91506000801b821415801561381e5750808214155b92505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f3030333030310000000000000000000000000000000000000000000000000000815250906138cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138c69190614340565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f3030333030360000000000000000000000000000000000000000000000000000815250906139aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139a19190614340565b60405180910390fd5b506139b582826135df565b808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60008183613a239190614586565b905092915050565b60008183613a399190614555565b905092915050565b828054613a4d9061470e565b90600052602060002090601f016020900481019282613a6f5760008555613ab6565b82601f10613a8857805160ff1916838001178555613ab6565b82800160010185558215613ab6579182015b82811115613ab5578251825591602001919060010190613a9a565b5b509050613ac39190613ac7565b5090565b5b80821115613ae0576000816000905550600101613ac8565b5090565b6000613af7613af28461443d565b614418565b905082815260208101848484011115613b0f57600080fd5b613b1a8482856146cc565b509392505050565b600081359050613b31816149ab565b92915050565b600081519050613b46816149ab565b92915050565b600081359050613b5b816149c2565b92915050565b600081359050613b70816149d9565b92915050565b600081519050613b85816149d9565b92915050565b60008083601f840112613b9d57600080fd5b8235905067ffffffffffffffff811115613bb657600080fd5b602083019150836001820283011115613bce57600080fd5b9250929050565b600081359050613be4816149f0565b92915050565b600082601f830112613bfb57600080fd5b8135613c0b848260208601613ae4565b91505092915050565b600081359050613c2381614a07565b92915050565b600081359050613c3881614a1e565b92915050565b600081519050613c4d81614a1e565b92915050565b600060208284031215613c6557600080fd5b6000613c7384828501613b22565b91505092915050565b600060208284031215613c8e57600080fd5b6000613c9c84828501613b37565b91505092915050565b60008060408385031215613cb857600080fd5b6000613cc685828601613b22565b9250506020613cd785828601613b22565b9150509250929050565b600080600060608486031215613cf657600080fd5b6000613d0486828701613b22565b9350506020613d1586828701613b22565b9250506040613d2686828701613c29565b9150509250925092565b600080600080600060808688031215613d4857600080fd5b6000613d5688828901613b22565b9550506020613d6788828901613b22565b9450506040613d7888828901613c29565b935050606086013567ffffffffffffffff811115613d9557600080fd5b613da188828901613b8b565b92509250509295509295909350565b60008060408385031215613dc357600080fd5b6000613dd185828601613b22565b9250506020613de285828601613b4c565b9150509250929050565b60008060408385031215613dff57600080fd5b6000613e0d85828601613b22565b9250506020613e1e85828601613c29565b9150509250929050565b600060208284031215613e3a57600080fd5b6000613e4884828501613b61565b91505092915050565b600060208284031215613e6357600080fd5b6000613e7184828501613b76565b91505092915050565b600060208284031215613e8c57600080fd5b6000613e9a84828501613bd5565b91505092915050565b600060208284031215613eb557600080fd5b600082013567ffffffffffffffff811115613ecf57600080fd5b613edb84828501613bea565b91505092915050565b600060208284031215613ef657600080fd5b6000613f0484828501613c14565b91505092915050565b600060208284031215613f1f57600080fd5b6000613f2d84828501613c29565b91505092915050565b600060208284031215613f4857600080fd5b6000613f5684828501613c3e565b91505092915050565b6000613f6b83836141e2565b60208301905092915050565b613f8081614614565b82525050565b6000613f9182614493565b613f9b81856144c1565b9350613fa68361446e565b8060005b83811015613fd7578151613fbe8882613f5f565b9750613fc9836144b4565b925050600181019050613faa565b5085935050505092915050565b613fed81614626565b82525050565b6000613ffe8261449e565b61400881856144d2565b93506140188185602086016146db565b614021816148a7565b840191505092915050565b614035816146a8565b82525050565b6000614046826144a9565b61405081856144e3565b93506140608185602086016146db565b614069816148a7565b840191505092915050565b600061407f826144a9565b61408981856144f4565b93506140998185602086016146db565b80840191505092915050565b600081546140b28161470e565b6140bc81866144f4565b945060018216600081146140d757600181146140e85761411b565b60ff1983168652818601935061411b565b6140f18561447e565b60005b83811015614113578154818901526001820191506020810190506140f4565b838801955050505b50505092915050565b60006141316026836144e3565b915061413c826148b8565b604082019050919050565b60006141546005836144f4565b915061415f82614907565b600582019050919050565b60006141776020836144e3565b915061418282614930565b602082019050919050565b600061419a6019836144e3565b91506141a582614959565b602082019050919050565b60006141bd6008836144e3565b91506141c882614982565b602082019050919050565b6141dc81614670565b82525050565b6141eb8161469e565b82525050565b6141fa8161469e565b82525050565b600061420c82856140a5565b91506142188284614074565b915061422382614147565b91508190509392505050565b60006020820190506142446000830184613f77565b92915050565b600060408201905061425f6000830185613f77565b61426c6020830184613f77565b9392505050565b60006080820190506142886000830187613f77565b6142956020830186613f77565b6142a260408301856141f1565b81810360608301526142b48184613ff3565b905095945050505050565b60006040820190506142d46000830185613f77565b6142e160208301846141f1565b9392505050565b600060208201905081810360008301526143028184613f86565b905092915050565b600060208201905061431f6000830184613fe4565b92915050565b600060208201905061433a600083018461402c565b92915050565b6000602082019050818103600083015261435a818461403b565b905092915050565b6000602082019050818103600083015261437b81614124565b9050919050565b6000602082019050818103600083015261439b8161416a565b9050919050565b600060208201905081810360008301526143bb8161418d565b9050919050565b600060208201905081810360008301526143db816141b0565b9050919050565b60006020820190506143f760008301846141d3565b92915050565b600060208201905061441260008301846141f1565b92915050565b6000614422614433565b905061442e8282614740565b919050565b6000604051905090565b600067ffffffffffffffff82111561445857614457614878565b5b614461826148a7565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061450a8261469e565b91506145158361469e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561454a576145496147eb565b5b828201905092915050565b60006145608261469e565b915061456b8361469e565b92508261457b5761457a61481a565b5b828204905092915050565b60006145918261469e565b915061459c8361469e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145d5576145d46147eb565b5b828202905092915050565b60006145eb8261469e565b91506145f68361469e565b925082821015614609576146086147eb565b5b828203905092915050565b600061461f8261467e565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600061466982614614565b9050919050565b600061ffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006146b3826146ba565b9050919050565b60006146c58261467e565b9050919050565b82818337600083830152505050565b60005b838110156146f95780820151818401526020810190506146de565b83811115614708576000848401525b50505050565b6000600282049050600182168061472657607f821691505b6020821081141561473a57614739614849565b5b50919050565b614749826148a7565b810181811067ffffffffffffffff8211171561476857614767614878565b5b80604052505050565b600061477c8261469e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156147af576147ae6147eb565b5b600182019050919050565b60006147c58261469e565b91506147d08361469e565b9250826147e0576147df61481a565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f416d6f756e74206973206c657373207468616e20707269636500000000000000600082015250565b7f536f6c64206f7574000000000000000000000000000000000000000000000000600082015250565b6149b481614614565b81146149bf57600080fd5b50565b6149cb81614626565b81146149d657600080fd5b50565b6149e281614632565b81146149ed57600080fd5b50565b6149f98161465e565b8114614a0457600080fd5b50565b614a1081614670565b8114614a1b57600080fd5b50565b614a278161469e565b8114614a3257600080fd5b5056fea264697066735822122029a71587885fc4917d56b25cc11e39f6b22e88783bb02da93fd6aeb88c93d5f564736f6c63430008040033
Deployed ByteCode Sourcemap
49349:3522:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8545:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33927:94;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17552:159;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;15472:319;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51630:86;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35164:94;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49579:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14745:314;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35798:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51276:126;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50912:100;;;;;;;;;;;;;:::i;:::-;;14024:156;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35393:175;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17131:184;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50000:770;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;16688:180;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42062:85;;;;;;;;;;;;;:::i;:::-;;49644:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50775:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51017:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;41471:78;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34132:102;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49523:52;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49437:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16194:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51462:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13439:184;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;34381:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49486:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17973:165;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51139:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42287:190;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;8545:150;8637:4;8657:19;:33;8677:12;8657:33;;;;;;;;;;;;;;;;;;;;;;;;;;;8650:40;;8545:150;;;:::o;33927:94::-;33975:19;34009:7;34001:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33927:94;:::o;17552:159::-;17661:7;17639:8;12430:1;12399:33;;:9;:19;12409:8;12399:19;;;;;;;;;;;;;;;;;;;;;:33;;;;12434:13;;;;;;;;;;;;;;;;;12391:57;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;17684:12:::1;:22;17697:8;17684:22;;;;;;;;;;;;;;;;;;;;;17677:29;;17552:159:::0;;;;:::o;15472:319::-;15564:8;11648:18;11669:9;:19;11679:8;11669:19;;;;;;;;;;;;;;;;;;;;;11648:40;;11720:10;11706:24;;:10;:24;;;:73;;;;11739:16;:28;11756:10;11739:28;;;;;;;;;;;;;;;:40;11768:10;11739:40;;;;;;;;;;;;;;;;;;;;;;;;;11706:73;11785:21;;;;;;;;;;;;;;;;;11693:118;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;15590:8:::1;12430:1;12399:33;;:9;:19;12409:8;12399:19;;;;;;;;;;;;;;;;;;;;;:33;;;;12434:13;;;;;;;;;;;;;;;;::::0;12391:57:::1;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;15607:18:::2;15628:9;:19;15638:8;15628:19;;;;;;;;;;;;;;;;;;;;;15607:40;;15673:10;15660:23;;:9;:23;;;;15685:8;;;;;;;;;;;;;;;;::::0;15652:42:::2;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;15726:9;15701:12;:22;15714:8;15701:22;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;15777:8;15766:9;15745:41;;15754:10;15745:41;;;;;;;;;;;;12453:1;11816::::1;15472:319:::0;;;;:::o;51630:86::-;41675:12;:10;:12::i;:::-;41664:23;;:7;:5;:7::i;:::-;:23;;;41656:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;51702:9:::1;51691:8;;:20;;;;;;;;;;;;;;;;;;51630:86:::0;:::o;35164:94::-;35219:7;35240:6;:13;;;;35233:20;;35164:94;:::o;49579:29::-;;;;;;;;;;;;;:::o;14745:314::-;14856:8;12000:18;12021:9;:19;12031:8;12021:19;;;;;;;;;;;;;;;;;;;;;12000:40;;12072:10;12058:24;;:10;:24;;;:69;;;;12117:10;12091:36;;:12;:22;12104:8;12091:22;;;;;;;;;;;;;;;;;;;;;:36;;;12058:69;:118;;;;12136:16;:28;12153:10;12136:28;;;;;;;;;;;;;;;:40;12165:10;12136:40;;;;;;;;;;;;;;;;;;;;;;;;;12058:118;12182:30;;;;;;;;;;;;;;;;;12045:172;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;14879:8:::1;12430:1;12399:33;;:9;:19;12409:8;12399:19;;;;;;;;;;;;;;;;;;;;;:33;;;;12434:13;;;;;;;;;;;;;;;;::::0;12391:57:::1;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;14894:18:::2;14915:9;:19;14925:8;14915:19;;;;;;;;;;;;;;;;;;;;;14894:40;;14961:5;14947:19;;:10;:19;;;14968:9;;;;;;;;;;;;;;;;::::0;14939:39:::2;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;15006:1;14991:17;;:3;:17;;;;15010:12;;;;;;;;;;;;;;;;::::0;14983:40:::2;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;15030:24;15040:3;15045:8;15030:9;:24::i;:::-;12453:1;12222::::1;14745:314:::0;;;;;:::o;35798:222::-;35903:7;35936:10;:18;35947:6;35936:18;;;;;;;;;;;;;;;:25;;;;35927:6;:34;35963:13;;;;;;;;;;;;;;;;;35919:58;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;35989:10;:18;36000:6;35989:18;;;;;;;;;;;;;;;36008:6;35989:26;;;;;;;;;;;;;;;;;;;;;;;;35982:33;;35798:222;;;;:::o;51276:126::-;41675:12;:10;:12::i;:::-;41664:23;;:7;:5;:7::i;:::-;:23;;;41656:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;51355:8:::1;51345:7;:18;;;;;;;;;;;;:::i;:::-;;51373:24;51388:8;51373:24;;;;;;:::i;:::-;;;;;;;;51276:126:::0;:::o;50912:100::-;41675:12;:10;:12::i;:::-;41664:23;;:7;:5;:7::i;:::-;:23;;;41656:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;50964:10:::1;50956:28;;:51;50985:21;50956:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;50912:100::o:0;14024:156::-;14132:43;14150:5;14157:3;14162:8;14132:43;;;;;;;;;;;;:17;:43::i;:::-;14024:156;;;:::o;35393:175::-;35475:7;35508:6;:13;;;;35499:6;:22;35523:13;;;;;;;;;;;;;;;;;35491:46;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;35549:6;35556;35549:14;;;;;;;;;;;;;;;;;;;;;;;;35542:21;;35393:175;;;:::o;17131:184::-;17210:14;17242:9;:19;17252:8;17242:19;;;;;;;;;;;;;;;;;;;;;17233:28;;17292:1;17274:20;;:6;:20;;;;17296:13;;;;;;;;;;;;;;;;;17266:44;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;17131:184;;;:::o;50000:770::-;50076:5;;50063:9;:18;;50055:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;50137:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50124:9;;:31;;50116:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;50175:13;50203:5;;50191:9;:17;;;;:::i;:::-;50175:33;;50236:1;50224:9;:13;:60;;;;;50282:1;50245:39;;50253:16;;;;;;;;;;;50245:39;;;;50224:60;:91;;;;;50313:1;50292:23;;:9;:23;;;;50224:91;:122;;;;;50336:10;50323:23;;:9;:23;;;;50224:122;50215:203;;;50358:16;;;;;;;;;;;:31;;;50390:10;50402:9;50358:54;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50215:203;50429:9;50424:342;50448:5;50444:1;:9;50424:342;;;50466:21;50490:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50466:42;;50516:15;50534:13;50516:31;;50553:10;50566;50553:23;;50584:24;50596:2;50600:7;50584:11;:24::i;:::-;50614:106;50639:7;50677;50686:17;50695:7;50686:8;:17::i;:::-;50660:53;;;;;;;;;:::i;:::-;;;;;;;;;;;;;50614:18;:106::i;:::-;50726:34;50738:10;50750:9;50726:11;:34::i;:::-;50424:342;;;50455:3;;;;;:::i;:::-;;;;50424:342;;;;50000:770;;:::o;16688:180::-;16767:7;16809:1;16791:20;;:6;:20;;;;16813:12;;;;;;;;;;;;;;;;;16783:43;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;16838:25;16856:6;16838:17;:25::i;:::-;16831:32;;16688:180;;;:::o;42062:85::-;41675:12;:10;:12::i;:::-;41664:23;;:7;:5;:7::i;:::-;:23;;;41656:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;42121:21:::1;42139:1;42121:9;:21::i;:::-;42062:85::o:0;49644:33::-;;;;;;;;;;;;;:::o;50775:132::-;50843:16;50875:27;50895:6;50875:19;:27::i;:::-;50868:34;;50775:132;;;:::o;51017:117::-;41675:12;:10;:12::i;:::-;41664:23;;:7;:5;:7::i;:::-;:23;;;41656:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;51087:9:::1;51079:5;:17;;;;51106:23;51119:9;51106:23;;;;;;:::i;:::-;;;;;;;;51017:117:::0;:::o;41471:78::-;41517:7;41538:6;;;;;;;;;;;41531:13;;41471:78;:::o;34132:102::-;34182:21;34220:9;34210:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34132:102;:::o;49523:52::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;49437:33::-;;;;:::o;16194:207::-;16329:9;16287:16;:28;16304:10;16287:28;;;;;;;;;;;;;;;:39;16316:9;16287:39;;;;;;;;;;;;;;;;:51;;;;;;;;;;;;;;;;;;16375:9;16348:48;;16363:10;16348:48;;;16386:9;16348:48;;;;;;:::i;:::-;;;;;;;;16194:207;;:::o;51462:118::-;41675:12;:10;:12::i;:::-;41664:23;;:7;:5;:7::i;:::-;:23;;;41656:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;51559:16:::1;51540;;:35;;;;;;;;;;;;;;;;;;51462:118:::0;:::o;13439:184::-;13572:46;13590:5;13597:3;13602:8;13612:5;;13572:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:17;:46::i;:::-;13439:184;;;;;:::o;34381:157::-;34487:13;34465:8;12430:1;12399:33;;:9;:19;12409:8;12399:19;;;;;;;;;;;;;;;;;;;;;:33;;;;12434:13;;;;;;;;;;;;;;;;;12391:57;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;34516:7:::1;:17;34524:8;34516:17;;;;;;;;;;;34509:24;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34381:157:::0;;;;:::o;49486:33::-;;;;:::o;17973:165::-;18078:4;18098:16;:24;18115:6;18098:24;;;;;;;;;;;;;;;:35;18123:9;18098:35;;;;;;;;;;;;;;;;;;;;;;;;;18091:42;;17973:165;;;;:::o;51139:132::-;41675:12;:10;:12::i;:::-;41664:23;;:7;:5;:7::i;:::-;:23;;;41656:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;51218:10:::1;51206:9;:22;;;;51238:28;51255:10;51238:28;;;;;;:::i;:::-;;;;;;;;51139:132:::0;:::o;42287:190::-;41675:12;:10;:12::i;:::-;41664:23;;:7;:5;:7::i;:::-;:23;;;41656:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;42395:1:::1;42375:22;;:8;:22;;;;42362:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;42453:19;42463:8;42453:9;:19::i;:::-;42287:190:::0;:::o;40314:89::-;40367:7;40388:10;40381:17;;40314:89;:::o;18322:241::-;18386:12;18401:9;:19;18411:8;18401:19;;;;;;;;;;;;;;;;;;;;;18386:34;;18425:24;18440:8;18425:14;:24::i;:::-;18456:30;18471:4;18477:8;18456:14;:30::i;:::-;18491:26;18503:3;18508:8;18491:11;:26::i;:::-;18549:8;18544:3;18529:29;;18538:4;18529:29;;;;;;;;;;;;18322:241;;;:::o;21478:581::-;21607:8;12000:18;12021:9;:19;12031:8;12021:19;;;;;;;;;;;;;;;;;;;;;12000:40;;12072:10;12058:24;;:10;:24;;;:69;;;;12117:10;12091:36;;:12;:22;12104:8;12091:22;;;;;;;;;;;;;;;;;;;;;:36;;;12058:69;:118;;;;12136:16;:28;12153:10;12136:28;;;;;;;;;;;;;;;:40;12165:10;12136:40;;;;;;;;;;;;;;;;;;;;;;;;;12058:118;12182:30;;;;;;;;;;;;;;;;;12045:172;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;21630:8:::1;12430:1;12399:33;;:9;:19;12409:8;12399:19;;;;;;;;;;;;;;;;;;;;;:33;;;;12434:13;;;;;;;;;;;;;;;;::::0;12391:57:::1;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;21645:18:::2;21666:9;:19;21676:8;21666:19;;;;;;;;;;;;;;;;;;;;;21645:40;;21712:5;21698:19;;:10;:19;;;21719:9;;;;;;;;;;;;;;;;::::0;21690:39:::2;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;21757:1;21742:17;;:3;:17;;;;21761:12;;;;;;;;;;;;;;;;::::0;21734:40:::2;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;21781:24;21791:3;21796:8;21781:9;:24::i;:::-;21816:16;:3;:14;;;:16::i;:::-;21812:243;;;21840:13;21876:3;21856:41;;;21904:10;21921:5;21933:8;21948:5;21856:103;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21840:119;;10908:10;21989:24;;21979:34;;;:6;:34;;;;22020:23;;;;;;;;;;;;;;;;::::0;21965:84:::2;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;21812:243;;12453:1;12222::::1;21478:581:::0;;;;;;:::o;36402:178::-;36479:26;36491:3;36496:8;36479:11;:26::i;:::-;36510:6;36522:8;36510:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36574:1;36558:6;:13;;;;:17;;;;:::i;:::-;36536:9;:19;36546:8;36536:19;;;;;;;;;;;:39;;;;36402:178;;:::o;52276:592::-;52332:13;52542:1;52533:5;:10;52529:38;;;52551:10;;;;;;;;;;;;;;;;;;;;;52529:38;52571:12;52586:5;52571:20;;52596:14;52615:54;52630:1;52622:4;:9;52615:54;;52639:8;;;;;:::i;:::-;;;;52661:2;52653:10;;;;;:::i;:::-;;;52615:54;;;52673:19;52705:6;52695:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52673:39;;52717:121;52733:1;52724:5;:10;52717:121;;52752:1;52742:11;;;;;:::i;:::-;;;52810:2;52802:5;:10;;;;:::i;:::-;52789:2;:24;;;;:::i;:::-;52776:39;;52759:6;52766;52759:14;;;;;;;;;;;;;;;;;;;:56;;;;;;;;;;;52830:2;52821:11;;;;;:::i;:::-;;;52717:121;;;52856:6;52842:21;;;;;52276:592;;;;:::o;34924:134::-;35012:8;12430:1;12399:33;;:9;:19;12409:8;12399:19;;;;;;;;;;;;;;;;;;;;;:33;;;;12434:13;;;;;;;;;;;;;;;;;12391:57;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;35049:4:::1;35029:7;:17;35037:8;35029:17;;;;;;;;;;;:24;;;;;;;;;;;;:::i;:::-;;34924:134:::0;;;:::o;51785:486::-;51891:1;51854:39;;51862:16;;;;;;;;;;;51854:39;;;;:55;;;;;51908:1;51897:8;;;;;;;;;;;:12;;;51854:55;51850:417;;;51917:16;51936;;;;;;;;;;;:28;;;51965:3;51936:33;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51917:52;;51975:19;51997:32;52023:5;51997:21;52009:8;;;;;;;;;;;51997:21;;:7;:11;;:21;;;;:::i;:::-;:25;;:32;;;;:::i;:::-;51975:54;;52061:1;52041:22;;:8;:22;;;;:41;;;;;52081:1;52067:11;:15;52041:41;52037:225;;;52099:8;52091:26;;:39;52118:11;52091:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52139:16;;;;;;;;;;;:36;;;52176:8;52186:11;52139:59;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52233:8;52210:45;;52228:3;52210:45;;;52243:11;52210:45;;;;;;:::i;:::-;;;;;;;;52037:225;51850:417;;;51785:486;;:::o;39537:151::-;39635:7;39658:10;:18;39669:6;39658:18;;;;;;;;;;;;;;;:25;;;;39651:32;;39537:151;;;:::o;42482:152::-;42532:16;42551:6;;;;;;;;;;;42532:25;;42571:8;42562:6;;:17;;;;;;;;;;;;;;;;;;42620:8;42589:40;;42610:8;42589:40;;;;;;;;;;;;42482:152;;:::o;39112:137::-;39194:16;39226:10;:18;39237:6;39226:18;;;;;;;;;;;;;;;39219:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39112:137;;;:::o;22187:89::-;22249:12;:22;22262:8;22249:22;;;;;;;;;;;;22242:29;;;;;;;;;;;22187:89;:::o;37723:551::-;37853:5;37830:28;;:9;:19;37840:8;37830:19;;;;;;;;;;;;;;;;;;;;;:28;;;37860:9;;;;;;;;;;;;;;;;;37822:48;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;37882:9;:19;37892:8;37882:19;;;;;;;;;;;;37875:26;;;;;;;;;;;37908;37937:14;:24;37952:8;37937:24;;;;;;;;;;;;37908:53;;37966:22;38018:1;37991:10;:17;38002:5;37991:17;;;;;;;;;;;;;;;:24;;;;:28;;;;:::i;:::-;37966:53;;38048:18;38030:14;:36;38026:214;;38074:17;38094:10;:17;38105:5;38094:17;;;;;;;;;;;;;;;38112:14;38094:33;;;;;;;;;;;;;;;;;;;;;;;;38074:53;;38173:9;38133:10;:17;38144:5;38133:17;;;;;;;;;;;;;;;38151:18;38133:37;;;;;;;;;;;;;;;;;;;;;;;:49;;;;38216:18;38188:14;:25;38203:9;38188:25;;;;;;;;;;;:46;;;;38026:214;;38246:10;:17;38257:5;38246:17;;;;;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37723:551;;;;:::o;38538:286::-;38671:1;38640:33;;:9;:19;38650:8;38640:19;;;;;;;;;;;;;;;;;;;;;:33;;;38675:18;;;;;;;;;;;;;;;;;38632:62;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;38721:3;38699:9;:19;38709:8;38699:19;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;38731:10;:15;38742:3;38731:15;;;;;;;;;;;;;;;38752:8;38731:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38818:1;38793:10;:15;38804:3;38793:15;;;;;;;;;;;;;;;:22;;;;:26;;;;:::i;:::-;38766:14;:24;38781:8;38766:24;;;;;;;;;;;:53;;;;38538:286;;:::o;9180:749::-;9247:17;9673:16;9694:19;9716:66;9694:88;;;;9826:5;9814:18;9802:30;;9893:3;9881:15;;:8;:15;;:42;;;;;9912:11;9900:8;:23;;9881:42;9865:59;;9180:749;;;;;:::o;18945:260::-;19036:1;19021:17;;:3;:17;;;;19040:12;;;;;;;;;;;;;;;;;19013:40;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;19097:1;19066:33;;:9;:19;19076:8;19066:19;;;;;;;;;;;;;;;;;;;;;:33;;;19101:18;;;;;;;;;;;;;;;;;19058:62;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;19127:26;19139:3;19144:8;19127:11;:26::i;:::-;19191:8;19186:3;19165:35;;19182:1;19165:35;;;;;;;;;;;;18945:260;;:::o;45800:89::-;45858:7;45883:1;45879;:5;;;;:::i;:::-;45872:12;;45800:89;;;;:::o;46157:::-;46215:7;46240:1;46236;:5;;;;:::i;:::-;46229:12;;46157:89;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:345:1:-;85:5;110:66;126:49;168:6;126:49;:::i;:::-;110:66;:::i;:::-;101:75;;199:6;192:5;185:21;237:4;230:5;226:16;275:3;266:6;261:3;257:16;254:25;251:2;;;292:1;289;282:12;251:2;305:41;339:6;334:3;329;305:41;:::i;:::-;91:261;;;;;;:::o;358:139::-;404:5;442:6;429:20;420:29;;458:33;485:5;458:33;:::i;:::-;410:87;;;;:::o;503:143::-;560:5;591:6;585:13;576:22;;607:33;634:5;607:33;:::i;:::-;566:80;;;;:::o;652:133::-;695:5;733:6;720:20;711:29;;749:30;773:5;749:30;:::i;:::-;701:84;;;;:::o;791:137::-;836:5;874:6;861:20;852:29;;890:32;916:5;890:32;:::i;:::-;842:86;;;;:::o;934:141::-;990:5;1021:6;1015:13;1006:22;;1037:32;1063:5;1037:32;:::i;:::-;996:79;;;;:::o;1094:351::-;1151:8;1161:6;1211:3;1204:4;1196:6;1192:17;1188:27;1178:2;;1229:1;1226;1219:12;1178:2;1265:6;1252:20;1242:30;;1295:18;1287:6;1284:30;1281:2;;;1327:1;1324;1317:12;1281:2;1364:4;1356:6;1352:17;1340:29;;1418:3;1410:4;1402:6;1398:17;1388:8;1384:32;1381:41;1378:2;;;1435:1;1432;1425:12;1378:2;1168:277;;;;;:::o;1451:175::-;1515:5;1553:6;1540:20;1531:29;;1569:51;1614:5;1569:51;:::i;:::-;1521:105;;;;:::o;1646:273::-;1702:5;1751:3;1744:4;1736:6;1732:17;1728:27;1718:2;;1769:1;1766;1759:12;1718:2;1809:6;1796:20;1834:79;1909:3;1901:6;1894:4;1886:6;1882:17;1834:79;:::i;:::-;1825:88;;1708:211;;;;;:::o;1925:137::-;1970:5;2008:6;1995:20;1986:29;;2024:32;2050:5;2024:32;:::i;:::-;1976:86;;;;:::o;2068:139::-;2114:5;2152:6;2139:20;2130:29;;2168:33;2195:5;2168:33;:::i;:::-;2120:87;;;;:::o;2213:143::-;2270:5;2301:6;2295:13;2286:22;;2317:33;2344:5;2317:33;:::i;:::-;2276:80;;;;:::o;2362:262::-;2421:6;2470:2;2458:9;2449:7;2445:23;2441:32;2438:2;;;2486:1;2483;2476:12;2438:2;2529:1;2554:53;2599:7;2590:6;2579:9;2575:22;2554:53;:::i;:::-;2544:63;;2500:117;2428:196;;;;:::o;2630:284::-;2700:6;2749:2;2737:9;2728:7;2724:23;2720:32;2717:2;;;2765:1;2762;2755:12;2717:2;2808:1;2833:64;2889:7;2880:6;2869:9;2865:22;2833:64;:::i;:::-;2823:74;;2779:128;2707:207;;;;:::o;2920:407::-;2988:6;2996;3045:2;3033:9;3024:7;3020:23;3016:32;3013:2;;;3061:1;3058;3051:12;3013:2;3104:1;3129:53;3174:7;3165:6;3154:9;3150:22;3129:53;:::i;:::-;3119:63;;3075:117;3231:2;3257:53;3302:7;3293:6;3282:9;3278:22;3257:53;:::i;:::-;3247:63;;3202:118;3003:324;;;;;:::o;3333:552::-;3410:6;3418;3426;3475:2;3463:9;3454:7;3450:23;3446:32;3443:2;;;3491:1;3488;3481:12;3443:2;3534:1;3559:53;3604:7;3595:6;3584:9;3580:22;3559:53;:::i;:::-;3549:63;;3505:117;3661:2;3687:53;3732:7;3723:6;3712:9;3708:22;3687:53;:::i;:::-;3677:63;;3632:118;3789:2;3815:53;3860:7;3851:6;3840:9;3836:22;3815:53;:::i;:::-;3805:63;;3760:118;3433:452;;;;;:::o;3891:829::-;3988:6;3996;4004;4012;4020;4069:3;4057:9;4048:7;4044:23;4040:33;4037:2;;;4086:1;4083;4076:12;4037:2;4129:1;4154:53;4199:7;4190:6;4179:9;4175:22;4154:53;:::i;:::-;4144:63;;4100:117;4256:2;4282:53;4327:7;4318:6;4307:9;4303:22;4282:53;:::i;:::-;4272:63;;4227:118;4384:2;4410:53;4455:7;4446:6;4435:9;4431:22;4410:53;:::i;:::-;4400:63;;4355:118;4540:2;4529:9;4525:18;4512:32;4571:18;4563:6;4560:30;4557:2;;;4603:1;4600;4593:12;4557:2;4639:64;4695:7;4686:6;4675:9;4671:22;4639:64;:::i;:::-;4621:82;;;;4483:230;4027:693;;;;;;;;:::o;4726:401::-;4791:6;4799;4848:2;4836:9;4827:7;4823:23;4819:32;4816:2;;;4864:1;4861;4854:12;4816:2;4907:1;4932:53;4977:7;4968:6;4957:9;4953:22;4932:53;:::i;:::-;4922:63;;4878:117;5034:2;5060:50;5102:7;5093:6;5082:9;5078:22;5060:50;:::i;:::-;5050:60;;5005:115;4806:321;;;;;:::o;5133:407::-;5201:6;5209;5258:2;5246:9;5237:7;5233:23;5229:32;5226:2;;;5274:1;5271;5264:12;5226:2;5317:1;5342:53;5387:7;5378:6;5367:9;5363:22;5342:53;:::i;:::-;5332:63;;5288:117;5444:2;5470:53;5515:7;5506:6;5495:9;5491:22;5470:53;:::i;:::-;5460:63;;5415:118;5216:324;;;;;:::o;5546:260::-;5604:6;5653:2;5641:9;5632:7;5628:23;5624:32;5621:2;;;5669:1;5666;5659:12;5621:2;5712:1;5737:52;5781:7;5772:6;5761:9;5757:22;5737:52;:::i;:::-;5727:62;;5683:116;5611:195;;;;:::o;5812:282::-;5881:6;5930:2;5918:9;5909:7;5905:23;5901:32;5898:2;;;5946:1;5943;5936:12;5898:2;5989:1;6014:63;6069:7;6060:6;6049:9;6045:22;6014:63;:::i;:::-;6004:73;;5960:127;5888:206;;;;:::o;6100:298::-;6177:6;6226:2;6214:9;6205:7;6201:23;6197:32;6194:2;;;6242:1;6239;6232:12;6194:2;6285:1;6310:71;6373:7;6364:6;6353:9;6349:22;6310:71;:::i;:::-;6300:81;;6256:135;6184:214;;;;:::o;6404:375::-;6473:6;6522:2;6510:9;6501:7;6497:23;6493:32;6490:2;;;6538:1;6535;6528:12;6490:2;6609:1;6598:9;6594:17;6581:31;6639:18;6631:6;6628:30;6625:2;;;6671:1;6668;6661:12;6625:2;6699:63;6754:7;6745:6;6734:9;6730:22;6699:63;:::i;:::-;6689:73;;6552:220;6480:299;;;;:::o;6785:260::-;6843:6;6892:2;6880:9;6871:7;6867:23;6863:32;6860:2;;;6908:1;6905;6898:12;6860:2;6951:1;6976:52;7020:7;7011:6;7000:9;6996:22;6976:52;:::i;:::-;6966:62;;6922:116;6850:195;;;;:::o;7051:262::-;7110:6;7159:2;7147:9;7138:7;7134:23;7130:32;7127:2;;;7175:1;7172;7165:12;7127:2;7218:1;7243:53;7288:7;7279:6;7268:9;7264:22;7243:53;:::i;:::-;7233:63;;7189:117;7117:196;;;;:::o;7319:284::-;7389:6;7438:2;7426:9;7417:7;7413:23;7409:32;7406:2;;;7454:1;7451;7444:12;7406:2;7497:1;7522:64;7578:7;7569:6;7558:9;7554:22;7522:64;:::i;:::-;7512:74;;7468:128;7396:207;;;;:::o;7609:179::-;7678:10;7699:46;7741:3;7733:6;7699:46;:::i;:::-;7777:4;7772:3;7768:14;7754:28;;7689:99;;;;:::o;7794:118::-;7881:24;7899:5;7881:24;:::i;:::-;7876:3;7869:37;7859:53;;:::o;7948:732::-;8067:3;8096:54;8144:5;8096:54;:::i;:::-;8166:86;8245:6;8240:3;8166:86;:::i;:::-;8159:93;;8276:56;8326:5;8276:56;:::i;:::-;8355:7;8386:1;8371:284;8396:6;8393:1;8390:13;8371:284;;;8472:6;8466:13;8499:63;8558:3;8543:13;8499:63;:::i;:::-;8492:70;;8585:60;8638:6;8585:60;:::i;:::-;8575:70;;8431:224;8418:1;8415;8411:9;8406:14;;8371:284;;;8375:14;8671:3;8664:10;;8072:608;;;;;;;:::o;8686:109::-;8767:21;8782:5;8767:21;:::i;:::-;8762:3;8755:34;8745:50;;:::o;8801:360::-;8887:3;8915:38;8947:5;8915:38;:::i;:::-;8969:70;9032:6;9027:3;8969:70;:::i;:::-;8962:77;;9048:52;9093:6;9088:3;9081:4;9074:5;9070:16;9048:52;:::i;:::-;9125:29;9147:6;9125:29;:::i;:::-;9120:3;9116:39;9109:46;;8891:270;;;;;:::o;9167:167::-;9272:55;9321:5;9272:55;:::i;:::-;9267:3;9260:68;9250:84;;:::o;9340:364::-;9428:3;9456:39;9489:5;9456:39;:::i;:::-;9511:71;9575:6;9570:3;9511:71;:::i;:::-;9504:78;;9591:52;9636:6;9631:3;9624:4;9617:5;9613:16;9591:52;:::i;:::-;9668:29;9690:6;9668:29;:::i;:::-;9663:3;9659:39;9652:46;;9432:272;;;;;:::o;9710:377::-;9816:3;9844:39;9877:5;9844:39;:::i;:::-;9899:89;9981:6;9976:3;9899:89;:::i;:::-;9892:96;;9997:52;10042:6;10037:3;10030:4;10023:5;10019:16;9997:52;:::i;:::-;10074:6;10069:3;10065:16;10058:23;;9820:267;;;;;:::o;10117:845::-;10220:3;10257:5;10251:12;10286:36;10312:9;10286:36;:::i;:::-;10338:89;10420:6;10415:3;10338:89;:::i;:::-;10331:96;;10458:1;10447:9;10443:17;10474:1;10469:137;;;;10620:1;10615:341;;;;10436:520;;10469:137;10553:4;10549:9;10538;10534:25;10529:3;10522:38;10589:6;10584:3;10580:16;10573:23;;10469:137;;10615:341;10682:38;10714:5;10682:38;:::i;:::-;10742:1;10756:154;10770:6;10767:1;10764:13;10756:154;;;10844:7;10838:14;10834:1;10829:3;10825:11;10818:35;10894:1;10885:7;10881:15;10870:26;;10792:4;10789:1;10785:12;10780:17;;10756:154;;;10939:6;10934:3;10930:16;10923:23;;10622:334;;10436:520;;10224:738;;;;;;:::o;10968:366::-;11110:3;11131:67;11195:2;11190:3;11131:67;:::i;:::-;11124:74;;11207:93;11296:3;11207:93;:::i;:::-;11325:2;11320:3;11316:12;11309:19;;11114:220;;;:::o;11340:400::-;11500:3;11521:84;11603:1;11598:3;11521:84;:::i;:::-;11514:91;;11614:93;11703:3;11614:93;:::i;:::-;11732:1;11727:3;11723:11;11716:18;;11504:236;;;:::o;11746:366::-;11888:3;11909:67;11973:2;11968:3;11909:67;:::i;:::-;11902:74;;11985:93;12074:3;11985:93;:::i;:::-;12103:2;12098:3;12094:12;12087:19;;11892:220;;;:::o;12118:366::-;12260:3;12281:67;12345:2;12340:3;12281:67;:::i;:::-;12274:74;;12357:93;12446:3;12357:93;:::i;:::-;12475:2;12470:3;12466:12;12459:19;;12264:220;;;:::o;12490:365::-;12632:3;12653:66;12717:1;12712:3;12653:66;:::i;:::-;12646:73;;12728:93;12817:3;12728:93;:::i;:::-;12846:2;12841:3;12837:12;12830:19;;12636:219;;;:::o;12861:115::-;12946:23;12963:5;12946:23;:::i;:::-;12941:3;12934:36;12924:52;;:::o;12982:108::-;13059:24;13077:5;13059:24;:::i;:::-;13054:3;13047:37;13037:53;;:::o;13096:118::-;13183:24;13201:5;13183:24;:::i;:::-;13178:3;13171:37;13161:53;;:::o;13220:695::-;13498:3;13520:92;13608:3;13599:6;13520:92;:::i;:::-;13513:99;;13629:95;13720:3;13711:6;13629:95;:::i;:::-;13622:102;;13741:148;13885:3;13741:148;:::i;:::-;13734:155;;13906:3;13899:10;;13502:413;;;;;:::o;13921:222::-;14014:4;14052:2;14041:9;14037:18;14029:26;;14065:71;14133:1;14122:9;14118:17;14109:6;14065:71;:::i;:::-;14019:124;;;;:::o;14149:332::-;14270:4;14308:2;14297:9;14293:18;14285:26;;14321:71;14389:1;14378:9;14374:17;14365:6;14321:71;:::i;:::-;14402:72;14470:2;14459:9;14455:18;14446:6;14402:72;:::i;:::-;14275:206;;;;;:::o;14487:640::-;14682:4;14720:3;14709:9;14705:19;14697:27;;14734:71;14802:1;14791:9;14787:17;14778:6;14734:71;:::i;:::-;14815:72;14883:2;14872:9;14868:18;14859:6;14815:72;:::i;:::-;14897;14965:2;14954:9;14950:18;14941:6;14897:72;:::i;:::-;15016:9;15010:4;15006:20;15001:2;14990:9;14986:18;14979:48;15044:76;15115:4;15106:6;15044:76;:::i;:::-;15036:84;;14687:440;;;;;;;:::o;15133:332::-;15254:4;15292:2;15281:9;15277:18;15269:26;;15305:71;15373:1;15362:9;15358:17;15349:6;15305:71;:::i;:::-;15386:72;15454:2;15443:9;15439:18;15430:6;15386:72;:::i;:::-;15259:206;;;;;:::o;15471:373::-;15614:4;15652:2;15641:9;15637:18;15629:26;;15701:9;15695:4;15691:20;15687:1;15676:9;15672:17;15665:47;15729:108;15832:4;15823:6;15729:108;:::i;:::-;15721:116;;15619:225;;;;:::o;15850:210::-;15937:4;15975:2;15964:9;15960:18;15952:26;;15988:65;16050:1;16039:9;16035:17;16026:6;15988:65;:::i;:::-;15942:118;;;;:::o;16066:258::-;16177:4;16215:2;16204:9;16200:18;16192:26;;16228:89;16314:1;16303:9;16299:17;16290:6;16228:89;:::i;:::-;16182:142;;;;:::o;16330:313::-;16443:4;16481:2;16470:9;16466:18;16458:26;;16530:9;16524:4;16520:20;16516:1;16505:9;16501:17;16494:47;16558:78;16631:4;16622:6;16558:78;:::i;:::-;16550:86;;16448:195;;;;:::o;16649:419::-;16815:4;16853:2;16842:9;16838:18;16830:26;;16902:9;16896:4;16892:20;16888:1;16877:9;16873:17;16866:47;16930:131;17056:4;16930:131;:::i;:::-;16922:139;;16820:248;;;:::o;17074:419::-;17240:4;17278:2;17267:9;17263:18;17255:26;;17327:9;17321:4;17317:20;17313:1;17302:9;17298:17;17291:47;17355:131;17481:4;17355:131;:::i;:::-;17347:139;;17245:248;;;:::o;17499:419::-;17665:4;17703:2;17692:9;17688:18;17680:26;;17752:9;17746:4;17742:20;17738:1;17727:9;17723:17;17716:47;17780:131;17906:4;17780:131;:::i;:::-;17772:139;;17670:248;;;:::o;17924:419::-;18090:4;18128:2;18117:9;18113:18;18105:26;;18177:9;18171:4;18167:20;18163:1;18152:9;18148:17;18141:47;18205:131;18331:4;18205:131;:::i;:::-;18197:139;;18095:248;;;:::o;18349:218::-;18440:4;18478:2;18467:9;18463:18;18455:26;;18491:69;18557:1;18546:9;18542:17;18533:6;18491:69;:::i;:::-;18445:122;;;;:::o;18573:222::-;18666:4;18704:2;18693:9;18689:18;18681:26;;18717:71;18785:1;18774:9;18770:17;18761:6;18717:71;:::i;:::-;18671:124;;;;:::o;18801:129::-;18835:6;18862:20;;:::i;:::-;18852:30;;18891:33;18919:4;18911:6;18891:33;:::i;:::-;18842:88;;;:::o;18936:75::-;18969:6;19002:2;18996:9;18986:19;;18976:35;:::o;19017:308::-;19079:4;19169:18;19161:6;19158:30;19155:2;;;19191:18;;:::i;:::-;19155:2;19229:29;19251:6;19229:29;:::i;:::-;19221:37;;19313:4;19307;19303:15;19295:23;;19084:241;;;:::o;19331:132::-;19398:4;19421:3;19413:11;;19451:4;19446:3;19442:14;19434:22;;19403:60;;;:::o;19469:141::-;19518:4;19541:3;19533:11;;19564:3;19561:1;19554:14;19598:4;19595:1;19585:18;19577:26;;19523:87;;;:::o;19616:114::-;19683:6;19717:5;19711:12;19701:22;;19690:40;;;:::o;19736:98::-;19787:6;19821:5;19815:12;19805:22;;19794:40;;;:::o;19840:99::-;19892:6;19926:5;19920:12;19910:22;;19899:40;;;:::o;19945:113::-;20015:4;20047;20042:3;20038:14;20030:22;;20020:38;;;:::o;20064:184::-;20163:11;20197:6;20192:3;20185:19;20237:4;20232:3;20228:14;20213:29;;20175:73;;;;:::o;20254:168::-;20337:11;20371:6;20366:3;20359:19;20411:4;20406:3;20402:14;20387:29;;20349:73;;;;:::o;20428:169::-;20512:11;20546:6;20541:3;20534:19;20586:4;20581:3;20577:14;20562:29;;20524:73;;;;:::o;20603:148::-;20705:11;20742:3;20727:18;;20717:34;;;;:::o;20757:305::-;20797:3;20816:20;20834:1;20816:20;:::i;:::-;20811:25;;20850:20;20868:1;20850:20;:::i;:::-;20845:25;;21004:1;20936:66;20932:74;20929:1;20926:81;20923:2;;;21010:18;;:::i;:::-;20923:2;21054:1;21051;21047:9;21040:16;;20801:261;;;;:::o;21068:185::-;21108:1;21125:20;21143:1;21125:20;:::i;:::-;21120:25;;21159:20;21177:1;21159:20;:::i;:::-;21154:25;;21198:1;21188:2;;21203:18;;:::i;:::-;21188:2;21245:1;21242;21238:9;21233:14;;21110:143;;;;:::o;21259:348::-;21299:7;21322:20;21340:1;21322:20;:::i;:::-;21317:25;;21356:20;21374:1;21356:20;:::i;:::-;21351:25;;21544:1;21476:66;21472:74;21469:1;21466:81;21461:1;21454:9;21447:17;21443:105;21440:2;;;21551:18;;:::i;:::-;21440:2;21599:1;21596;21592:9;21581:20;;21307:300;;;;:::o;21613:191::-;21653:4;21673:20;21691:1;21673:20;:::i;:::-;21668:25;;21707:20;21725:1;21707:20;:::i;:::-;21702:25;;21746:1;21743;21740:8;21737:2;;;21751:18;;:::i;:::-;21737:2;21796:1;21793;21789:9;21781:17;;21658:146;;;;:::o;21810:96::-;21847:7;21876:24;21894:5;21876:24;:::i;:::-;21865:35;;21855:51;;;:::o;21912:90::-;21946:7;21989:5;21982:13;21975:21;21964:32;;21954:48;;;:::o;22008:149::-;22044:7;22084:66;22077:5;22073:78;22062:89;;22052:105;;;:::o;22163:114::-;22218:7;22247:24;22265:5;22247:24;:::i;:::-;22236:35;;22226:51;;;:::o;22283:89::-;22319:7;22359:6;22352:5;22348:18;22337:29;;22327:45;;;:::o;22378:126::-;22415:7;22455:42;22448:5;22444:54;22433:65;;22423:81;;;:::o;22510:77::-;22547:7;22576:5;22565:16;;22555:32;;;:::o;22593:162::-;22661:9;22694:55;22743:5;22694:55;:::i;:::-;22681:68;;22671:84;;;:::o;22761:131::-;22829:9;22862:24;22880:5;22862:24;:::i;:::-;22849:37;;22839:53;;;:::o;22898:154::-;22982:6;22977:3;22972;22959:30;23044:1;23035:6;23030:3;23026:16;23019:27;22949:103;;;:::o;23058:307::-;23126:1;23136:113;23150:6;23147:1;23144:13;23136:113;;;23235:1;23230:3;23226:11;23220:18;23216:1;23211:3;23207:11;23200:39;23172:2;23169:1;23165:10;23160:15;;23136:113;;;23267:6;23264:1;23261:13;23258:2;;;23347:1;23338:6;23333:3;23329:16;23322:27;23258:2;23107:258;;;;:::o;23371:320::-;23415:6;23452:1;23446:4;23442:12;23432:22;;23499:1;23493:4;23489:12;23520:18;23510:2;;23576:4;23568:6;23564:17;23554:27;;23510:2;23638;23630:6;23627:14;23607:18;23604:38;23601:2;;;23657:18;;:::i;:::-;23601:2;23422:269;;;;:::o;23697:281::-;23780:27;23802:4;23780:27;:::i;:::-;23772:6;23768:40;23910:6;23898:10;23895:22;23874:18;23862:10;23859:34;23856:62;23853:2;;;23921:18;;:::i;:::-;23853:2;23961:10;23957:2;23950:22;23740:238;;;:::o;23984:233::-;24023:3;24046:24;24064:5;24046:24;:::i;:::-;24037:33;;24092:66;24085:5;24082:77;24079:2;;;24162:18;;:::i;:::-;24079:2;24209:1;24202:5;24198:13;24191:20;;24027:190;;;:::o;24223:176::-;24255:1;24272:20;24290:1;24272:20;:::i;:::-;24267:25;;24306:20;24324:1;24306:20;:::i;:::-;24301:25;;24345:1;24335:2;;24350:18;;:::i;:::-;24335:2;24391:1;24388;24384:9;24379:14;;24257:142;;;;:::o;24405:180::-;24453:77;24450:1;24443:88;24550:4;24547:1;24540:15;24574:4;24571:1;24564:15;24591:180;24639:77;24636:1;24629:88;24736:4;24733:1;24726:15;24760:4;24757:1;24750:15;24777:180;24825:77;24822:1;24815:88;24922:4;24919:1;24912:15;24946:4;24943:1;24936:15;24963:180;25011:77;25008:1;25001:88;25108:4;25105:1;25098:15;25132:4;25129:1;25122:15;25149:102;25190:6;25241:2;25237:7;25232:2;25225:5;25221:14;25217:28;25207:38;;25197:54;;;:::o;25257:225::-;25397:34;25393:1;25385:6;25381:14;25374:58;25466:8;25461:2;25453:6;25449:15;25442:33;25363:119;:::o;25488:155::-;25628:7;25624:1;25616:6;25612:14;25605:31;25594:49;:::o;25649:182::-;25789:34;25785:1;25777:6;25773:14;25766:58;25755:76;:::o;25837:175::-;25977:27;25973:1;25965:6;25961:14;25954:51;25943:69;:::o;26018:158::-;26158:10;26154:1;26146:6;26142:14;26135:34;26124:52;:::o;26182:122::-;26255:24;26273:5;26255:24;:::i;:::-;26248:5;26245:35;26235:2;;26294:1;26291;26284:12;26235:2;26225:79;:::o;26310:116::-;26380:21;26395:5;26380:21;:::i;:::-;26373:5;26370:32;26360:2;;26416:1;26413;26406:12;26360:2;26350:76;:::o;26432:120::-;26504:23;26521:5;26504:23;:::i;:::-;26497:5;26494:34;26484:2;;26542:1;26539;26532:12;26484:2;26474:78;:::o;26558:158::-;26649:42;26685:5;26649:42;:::i;:::-;26642:5;26639:53;26629:2;;26706:1;26703;26696:12;26629:2;26619:97;:::o;26722:120::-;26794:23;26811:5;26794:23;:::i;:::-;26787:5;26784:34;26774:2;;26832:1;26829;26822:12;26774:2;26764:78;:::o;26848:122::-;26921:24;26939:5;26921:24;:::i;:::-;26914:5;26911:35;26901:2;;26960:1;26957;26950:12;26901:2;26891:79;:::o
Metadata Hash
ipfs://29a71587885fc4917d56b25cc11e39f6b22e88783bb02da93fd6aeb88c93d5f5