Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
419 CARRIER
Holders
72
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
9 CARRIERLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
MCPetCarriers
Compiler Version
v0.8.10+commit.fc410830
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; import "./ERC721ABurnable.sol"; import "./ERC721A.sol"; import "./Ownable.sol"; import "./Strings.sol"; import "./ReentrancyGuard.sol"; import {DefaultOperatorFilterer} from "./DefaultOperatorFilterer.sol"; contract OwnableDelegateProxy {} /** * Used to delegate ownership of a contract to another address, to save on unneeded transactions to approve contract use for users */ contract ProxyRegistry { mapping(address => OwnableDelegateProxy) public proxies; } contract MCPetCarriers is ERC721ABurnable, DefaultOperatorFilterer, Ownable, ReentrancyGuard { using Strings for uint256; string public baseURI; uint256 public totalWithdrawn = 0; uint256 public maxSupply = 3000; uint256 public maxMint = 30; // max per transaction bool public claimingDisabled = false; bool public redeemingDisabled = true; bool public burningDisabled = true; address public constant MASTERCATS_CONTRACT = 0xF03c4e6b6187AcA96B18162CBb4468FC6E339120; address public constant MASTERCATS_VAULT = 0x7d0b3f2F241CaeDE2d6d885Bb6d7f149ecdfba24; address public constant SIGNER = 0x918de5F6A7411219D7ea785DCe2d5D6B120B2912; string _name = "MC Pet Carriers"; string _symbol = "CARRIER"; string _initBaseURI = "https://mastercatsnft.io:7777/api/tokens/carriers/"; address public proxyRegistryAddress = 0xa5409ec958C83C3f309868babACA7c86DCB077c1; // OpenSea Mainnet Proxy Registry address constructor() ERC721A(_name, _symbol) { setBaseURI(_initBaseURI); } function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public payable override onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public payable override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } /* claim signature verification */ function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature) private pure returns (address) { (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature); return ecrecover(_ethSignedMessageHash, v, r, s); } function splitSignature(bytes memory sig) private pure returns (bytes32 r, bytes32 s, uint8 v) { require(sig.length == 65, "Invalid signature length"); assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := byte(0, mload(add(sig, 96))) } } function checkClaimSignature(address user, bytes memory signature, uint256 userMaxAllowance) public pure returns (bool) { bytes32 messageHash = keccak256(abi.encodePacked(user, userMaxAllowance)); bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash)); return recoverSigner(ethSignedMessageHash, signature) == SIGNER; } function checkRedeemSignature(address user, bytes memory signature, uint256[] calldata carrierIds, uint256[] calldata catIds) public pure returns (bool) { bytes32 messageHash = keccak256(abi.encodePacked(carrierIds, user, catIds)); bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash)); return recoverSigner(ethSignedMessageHash, signature) == SIGNER; } // public redeem (burn) pet carrier to receive cat - requires signature function redeemCarrier(uint256[] calldata carrierIds, uint256[] calldata catIds, bytes memory signature) external nonReentrant { require(!redeemingDisabled, "Redeeming has been disabled"); require(carrierIds.length == catIds.length, "Invalid carrierIds and catIds (length mismatch)"); require(checkRedeemSignature(msg.sender, signature, carrierIds, catIds), "Signature invalid"); // verifies the carrier & cat ids for(uint256 i = 0; i < carrierIds.length; ++i) { _burn(carrierIds[i], true); // will fail if user does not own carrier/is not approved IERC721A(MASTERCATS_CONTRACT).safeTransferFrom(MASTERCATS_VAULT, msg.sender, catIds[i]); // will fail if the vault does not own the cat } } // public claim pet carrier - requires signature function claimCarrier(uint256 userMaxAllowance, uint256 claimQty, bytes memory signature) external nonReentrant { require(!claimingDisabled, "Claiming has been disabled"); require(checkClaimSignature(msg.sender, signature, userMaxAllowance), "Signature invalid"); // verifies their allowance uint256 userMinted = _numberMinted(msg.sender); // qty user has minted uint256 userCanMint = userMaxAllowance - userMinted; // qty user can mint based on existing mints and their allowance // restrict to maxMint limit per tx if(userCanMint > maxMint) { userCanMint = maxMint; } // restrict to max user can mint if(claimQty > userCanMint) { claimQty = userCanMint; } uint256 supply = _totalMinted(); // total minted globally require((supply + claimQty) <= maxSupply, "Exceeds max supply"); _mint(msg.sender, claimQty); delete supply; delete userMinted; delete userCanMint; } // admin minting function adminClaimCarrier(uint256[] calldata quantities, address[] calldata recipients) external onlyOwner { require(quantities.length == recipients.length, "Invalid quantities and recipients (length mismatch)"); uint256 totalQuantity = 0; uint256 supply = _totalMinted(); // total minted globally for (uint256 i = 0; i < quantities.length; ++i) { totalQuantity += quantities[i]; } require(supply + totalQuantity <= maxSupply, "Exceeds max mupply"); delete totalQuantity; for (uint256 i = 0; i < recipients.length; ++i) { _mint(recipients[i], quantities[i]); } delete supply; } function burn(uint256 tokenId) public virtual override { require(!burningDisabled, "Burning is disabled"); _burn(tokenId, true); } function batchTransferFrom(address _from, address _to, uint256[] memory _tokenIds) public { for (uint256 i = 0; i < _tokenIds.length; i++) { transferFrom(_from, _to, _tokenIds[i]); } } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: Nonexistent token"); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString())) : ""; } function setMaxMint(uint256 _maxMint) public onlyOwner { maxMint = _maxMint; } function setMaxSupply(uint256 _newMaxSupply) public onlyOwner { maxSupply = _newMaxSupply; } function setBaseURI(string memory _newBaseURI) public onlyOwner { baseURI = _newBaseURI; } function setClaimingDisabled(bool _claimingDisabled) public onlyOwner { claimingDisabled = _claimingDisabled; } function setRedeemingDisabled(bool _redeemingDisabled) public onlyOwner { redeemingDisabled = _redeemingDisabled; } function setBurningDisabled(bool _burningDisabled) public onlyOwner { burningDisabled = _burningDisabled; } function totalMinted() public view returns (uint256) { return _totalMinted(); } function numberMinted(address owner) public view returns (uint256) { return _numberMinted(owner); } function totalBurned() public view returns (uint256) { return _totalBurned(); } function numberBurned(address owner) public view returns (uint256) { return _numberBurned(owner); } function ownershipOf(uint256 tokenId) external view returns (TokenOwnership memory) { return _ownershipOf(tokenId); } function getTotalWithdrawn() public view returns (uint256) { return totalWithdrawn; } function getTotalBalance() public view returns (uint256) { return address(this).balance; } function getTotalRaised() public view returns (uint256) { return getTotalWithdrawn() + getTotalBalance(); } /** * withdraw ETH from the contract (callable by Owner only) */ function withdraw() public payable onlyOwner { uint256 val = address(this).balance; (bool success, ) = payable(msg.sender).call{ value: val }(""); require(success); totalWithdrawn += val; delete val; } /** * whitelist user's OpenSea proxy accounts to enable gas-less listings. */ function isApprovedForAll(address owner, address operator) override public view returns (bool) { // Whitelist OpenSea proxy contract for easy trading. ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); if (address(proxyRegistry.proxies(owner)) == operator) { return true; } return super.isApprovedForAll(owner, operator); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Address.sol) pragma solidity ^0.8.0; /** * @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); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import {OperatorFilterer} from "./OperatorFilterer.sol"; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721ABurnable.sol'; import './ERC721A.sol'; /** * @title ERC721ABurnable. * * @dev ERC721A token that can be irreversibly burned (destroyed). */ abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable { /** * @dev Burns `tokenId`. See {ERC721A-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual override { _burn(tokenId, true); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.10; import "./ERC721P.sol"; import "./IERC721Enumerable.sol"; abstract contract ERC721Enum is ERC721P, IERC721Enumerable { function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721P) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256 tokenId) { require(index < ERC721P.balanceOf(owner), "ERC721Enum: owner ioob"); uint256 count; for (uint256 i; i < _owners.length; ++i) { if (owner == _owners[i]) { if (count == index) return i; else ++count; } } require(false, "ERC721Enum: owner ioob"); } function tokensOfOwner(address owner) public view returns (uint256[] memory) { require(0 < ERC721P.balanceOf(owner), "ERC721Enum: owner ioob"); uint256 tokenCount = balanceOf(owner); uint256[] memory tokenIds = new uint256[](tokenCount); for (uint256 i = 0; i < tokenCount; i++) { tokenIds[i] = tokenOfOwnerByIndex(owner, i); } return tokenIds; } function totalSupply() public view virtual override returns (uint256) { return _owners.length; } function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enum.totalSupply(), "ERC721Enum: global ioob"); return index; } }
// SPDX-License-Identifier: GPL-3.0 // Thank you to ToyBoogers & Pagzi Tech for the optimised ERC721 pragma solidity ^0.8.10; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./IERC721Metadata.sol"; import "./Address.sol"; import "./Context.sol"; import "./ERC165.sol"; abstract contract ERC721P is Context, ERC165, IERC721, IERC721Metadata { using Address for address; string private _name; string private _symbol; address[] internal _owners; mapping(uint256 => address) private _tokenApprovals; mapping(address => mapping(address => bool)) private _operatorApprovals; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } function getOwners() external view returns (address[] memory) { return _owners; } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } function balanceOf(address owner) public view virtual override returns (uint256) { require( owner != address(0), "ERC721: balance query for the zero address" ); uint256 count = 0; uint256 length = _owners.length; for (uint256 i = 0; i < length; ++i) { if (owner == _owners[i]) { ++count; } } delete length; return count; } function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require( owner != address(0), "ERC721: owner query for nonexistent token" ); return owner; } function name() public view virtual override returns (string memory) { return _name; } function symbol() public view virtual override returns (string memory) { return _symbol; } function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721P.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } function getApproved(uint256 tokenId) public view virtual override returns (address) { require( _exists(tokenId), "ERC721: approved query for nonexistent token" ); return _tokenApprovals[tokenId]; } function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved" ); _transfer(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require( _isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved" ); _safeTransfer(from, to, tokenId, _data); } function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } function _exists(uint256 tokenId) internal view virtual returns (bool) { return tokenId < _owners.length && _owners[tokenId] != address(0); } function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require( _exists(tokenId), "ERC721: operator query for nonexistent token" ); address owner = ERC721P.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _owners.push(to); emit Transfer(address(0), to, tokenId); } function _burn(uint256 tokenId) internal virtual { address owner = ERC721P.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _owners[tokenId] = address(0); emit Transfer(owner, address(0), tokenId); } function _transfer( address from, address to, uint256 tokenId ) internal virtual { require( ERC721P.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own" ); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _owners[tokenId] = to; emit Transfer(from, to, tokenId); } function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721P.ownerOf(tokenId), to, tokenId); } function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received( _msgSender(), from, tokenId, _data ) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert( "ERC721: transfer to non ERC721Receiver implementer" ); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @dev Interface of ERC721ABurnable. */ interface IERC721ABurnable is IERC721A { /** * @dev Burns `tokenId`. See {ERC721A-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function unregister(address addr) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; /** * @title OperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. * @dev This smart contract is meant to be inherited by token contracts so they can use the following: * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. */ abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (subscribe) { OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { OPERATOR_FILTER_REGISTRY.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from != msg.sender) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } function _checkFilterOperator(address operator) internal view virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (access/Ownable.sol) pragma solidity ^0.8.0; import "./Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev 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 { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // 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); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MASTERCATS_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MASTERCATS_VAULT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"quantities","type":"uint256[]"},{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"adminClaimCarrier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","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":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"batchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burningDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"userMaxAllowance","type":"uint256"}],"name":"checkClaimSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256[]","name":"carrierIds","type":"uint256[]"},{"internalType":"uint256[]","name":"catIds","type":"uint256[]"}],"name":"checkRedeemSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"userMaxAllowance","type":"uint256"},{"internalType":"uint256","name":"claimQty","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"claimCarrier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimingDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalWithdrawn","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":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyRegistryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"carrierIds","type":"uint256[]"},{"internalType":"uint256[]","name":"catIds","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"redeemCarrier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemingDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_burningDisabled","type":"bool"}],"name":"setBurningDisabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_claimingDisabled","type":"bool"}],"name":"setClaimingDisabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMint","type":"uint256"}],"name":"setMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_redeemingDisabled","type":"bool"}],"name":"setRedeemingDisabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
6000600b55610bb8600c55601e600d55600e805462ffffff19166201010017905560c0604052600f60808190526e4d432050657420436172726965727360881b60a0908152620000519190816200051f565b506040805180820190915260078082526621a0a92924a2a960c91b602090920191825262000082916010916200051f565b5060405180606001604052806032815260200162003dbb603291398051620000b3916011916020909101906200051f565b50601280546001600160a01b03191673a5409ec958c83c3f309868babaca7c86dcb077c1179055348015620000e757600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb66001600f80546200010e90620005c5565b80601f01602080910402602001604051908101604052809291908181526020018280546200013c90620005c5565b80156200018d5780601f1062000161576101008083540402835291602001916200018d565b820191906000526020600020905b8154815290600101906020018083116200016f57829003601f168201915b505050505060108054620001a190620005c5565b80601f0160208091040260200160405190810160405280929190818152602001828054620001cf90620005c5565b8015620002205780601f10620001f45761010080835404028352916020019162000220565b820191906000526020600020905b8154815290600101906020018083116200020257829003601f168201915b505084516200023a9350600292506020860191506200051f565b508051620002509060039060208401906200051f565b506000805550506daaeb6d7670e522a718067333cd4e3b156200039c578015620002ea57604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b158015620002cb57600080fd5b505af1158015620002e0573d6000803e3d6000fd5b505050506200039c565b6001600160a01b038216156200033b5760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af290390604401620002b0565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200038257600080fd5b505af115801562000397573d6000803e3d6000fd5b505050505b50620003aa90503362000455565b6001600955601180546200044f9190620003c490620005c5565b80601f0160208091040260200160405190810160405280929190818152602001828054620003f290620005c5565b8015620004435780601f10620004175761010080835404028352916020019162000443565b820191906000526020600020905b8154815290600101906020018083116200042557829003601f168201915b5050620004a792505050565b62000602565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6008546001600160a01b03163314620005065760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b80516200051b90600a9060208401906200051f565b5050565b8280546200052d90620005c5565b90600052602060002090601f0160209004810192826200055157600085556200059c565b82601f106200056c57805160ff19168380011785556200059c565b828001600101855582156200059c579182015b828111156200059c5782518255916020019190600101906200057f565b50620005aa929150620005ae565b5090565b5b80821115620005aa5760008155600101620005af565b600181811c90821680620005da57607f821691505b60208210811415620005fc57634e487b7160e01b600052602260045260246000fd5b50919050565b6137a980620006126000396000f3fe6080604052600436106103345760003560e01c80636c0360eb116101b0578063b88d4fde116100ec578063d89135cd11610095578063f2a452981161006f578063f2a452981461091b578063f2fde38b1461093b578063f3993d111461095b578063fe3dbd811461097b57600080fd5b8063d89135cd146108c6578063dc33e681146108db578063e985e9c5146108fb57600080fd5b8063ce3dc5cf116100c6578063ce3dc5cf14610870578063d50e003614610890578063d5abeb01146108b057600080fd5b8063b88d4fde14610810578063c87b56dd14610823578063cd7c03261461084357600080fd5b80638da5cb5b116101595780639f550293116101335780639f550293146107a7578063a22cb465146107bc578063a2309ff8146107dc578063a7b7f222146107f157600080fd5b80638da5cb5b1461074757806395d89b411461077257806399edf7eb1461078757600080fd5b8063715018a61161018a578063715018a6146107075780637501f7411461071c57806389404a791461073257600080fd5b80636c0360eb146106b25780636f8b44b0146106c757806370a08231146106e757600080fd5b80633ccfd60b1161027f57806342966c6811610228578063547520fe11610202578063547520fe1461062a57806355f804b31461064a578063582abd121461066a5780636352211e1461069257600080fd5b806342966c68146105cc578063468f87f2146105ec5780634b3197131461061457600080fd5b80634193cdf8116102595780634193cdf81461057757806341f434341461059757806342842e0e146105b957600080fd5b80633ccfd60b146105275780633d43675a1461052f5780634121555e1461054f57600080fd5b806318160ddd116102e15780632478d639116102bb5780632478d639146104cd578063285e61d1146104ed57806332b9de9a1461050d57600080fd5b806318160ddd1461048157806323b872dd1461049a57806323d2bf1e146104ad57600080fd5b8063095ea7b311610312578063095ea7b3146103d557806312b58349146103ea578063140364a11461040757600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b50610359610354366004612d6f565b61099b565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610a80565b6040516103659190612e02565b34801561039c57600080fd5b506103b06103ab366004612e15565b610b12565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610365565b6103e86103e3366004612e50565b610b7c565b005b3480156103f657600080fd5b50475b604051908152602001610365565b34801561041357600080fd5b50610427610422366004612e15565b610b95565b6040516103659190815173ffffffffffffffffffffffffffffffffffffffff16815260208083015167ffffffffffffffff169082015260408083015115159082015260609182015162ffffff169181019190915260800190565b34801561048d57600080fd5b50600154600054036103f9565b6103e86104a8366004612e7c565b610bc2565b3480156104b957600080fd5b506103e86104c8366004612ecb565b610bfa565b3480156104d957600080fd5b506103f96104e8366004612ee8565b610c97565b3480156104f957600080fd5b50610359610508366004613019565b610cd2565b34801561051957600080fd5b50600e546103599060ff1681565b6103e8610dd5565b34801561053b57600080fd5b506103e861054a366004612ecb565b610eae565b34801561055b57600080fd5b506103b0737d0b3f2f241caede2d6d885bb6d7f149ecdfba2481565b34801561058357600080fd5b506103e86105923660046130be565b610f4d565b3480156105a357600080fd5b506103b06daaeb6d7670e522a718067333cd4e81565b6103e86105c7366004612e7c565b6111ee565b3480156105d857600080fd5b506103e86105e7366004612e15565b611220565b3480156105f857600080fd5b506103b073f03c4e6b6187aca96b18162cbb4468fc6e33912081565b34801561062057600080fd5b506103f9600b5481565b34801561063657600080fd5b506103e8610645366004612e15565b611287565b34801561065657600080fd5b506103e8610665366004613152565b6112f3565b34801561067657600080fd5b506103b073918de5f6a7411219d7ea785dce2d5d6b120b291281565b34801561069e57600080fd5b506103b06106ad366004612e15565b611371565b3480156106be57600080fd5b5061038361137c565b3480156106d357600080fd5b506103e86106e2366004612e15565b61140a565b3480156106f357600080fd5b506103f9610702366004612ee8565b611476565b34801561071357600080fd5b506103e86114f8565b34801561072857600080fd5b506103f9600d5481565b34801561073e57600080fd5b50600b546103f9565b34801561075357600080fd5b5060085473ffffffffffffffffffffffffffffffffffffffff166103b0565b34801561077e57600080fd5b5061038361156b565b34801561079357600080fd5b506103e86107a2366004612ecb565b61157a565b3480156107b357600080fd5b506103f9611618565b3480156107c857600080fd5b506103e86107d736600461319b565b61162d565b3480156107e857600080fd5b506000546103f9565b3480156107fd57600080fd5b50600e5461035990610100900460ff1681565b6103e861081e3660046131d4565b611641565b34801561082f57600080fd5b5061038361083e366004612e15565b61167b565b34801561084f57600080fd5b506012546103b09073ffffffffffffffffffffffffffffffffffffffff1681565b34801561087c57600080fd5b506103e861088b366004613240565b611754565b34801561089c57600080fd5b506103596108ab366004613290565b611903565b3480156108bc57600080fd5b506103f9600c5481565b3480156108d257600080fd5b506103f96119e7565b3480156108e757600080fd5b506103f96108f6366004612ee8565b6119f2565b34801561090757600080fd5b50610359610916366004613337565b611a2a565b34801561092757600080fd5b506103e8610936366004613365565b611b2b565b34801561094757600080fd5b506103e8610956366004612ee8565b611d22565b34801561096757600080fd5b506103e86109763660046133d1565b611e1b565b34801561098757600080fd5b50600e546103599062010000900460ff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161480610a2e57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b80610a7a57507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b606060028054610a8f9061349e565b80601f0160208091040260200160405190810160405280929190818152602001828054610abb9061349e565b8015610b085780601f10610add57610100808354040283529160200191610b08565b820191906000526020600020905b815481529060010190602001808311610aeb57829003601f168201915b5050505050905090565b6000610b1d82611e5d565b610b53576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060009081526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b81610b8681611e9d565b610b908383611fa2565b505050565b604080516080810182526000808252602082018190529181018290526060810191909152610a7a8261208d565b8273ffffffffffffffffffffffffffffffffffffffff81163314610be957610be933611e9d565b610bf484848461212b565b50505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610c665760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6000610a7a8273ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205460801c67ffffffffffffffff1690565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018290526000908190605401604051602081830303815290604052805190602001209050600081604051602001610d6791907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60405160208183030381529060405280519060200120905073918de5f6a7411219d7ea785dce2d5d6b120b291273ffffffffffffffffffffffffffffffffffffffff16610db482876123bd565b73ffffffffffffffffffffffffffffffffffffffff16149695505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610e3c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b6040514790600090339083908381818185875af1925050503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5050905080610e9357600080fd5b81600b6000828254610ea59190613521565b90915550505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610f155760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600e805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b60026009541415610fa05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c5d565b6002600955600e54610100900460ff1615610ffd5760405162461bcd60e51b815260206004820152601b60248201527f52656465656d696e6720686173206265656e2064697361626c656400000000006044820152606401610c5d565b8382146110725760405162461bcd60e51b815260206004820152602f60248201527f496e76616c6964206361727269657249647320616e642063617449647320286c60448201527f656e677468206d69736d617463682900000000000000000000000000000000006064820152608401610c5d565b611080338287878787611903565b6110cc5760405162461bcd60e51b815260206004820152601160248201527f5369676e617475726520696e76616c69640000000000000000000000000000006044820152606401610c5d565b60005b848110156111e1576110fa8686838181106110ec576110ec613539565b90506020020135600161245a565b73f03c4e6b6187aca96b18162cbb4468fc6e3391206342842e0e737d0b3f2f241caede2d6d885bb6d7f149ecdfba243387878681811061113c5761113c613539565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815273ffffffffffffffffffffffffffffffffffffffff958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b1580156111b857600080fd5b505af11580156111cc573d6000803e3d6000fd5b50505050806111da90613568565b90506110cf565b5050600160095550505050565b8273ffffffffffffffffffffffffffffffffffffffff811633146112155761121533611e9d565b610bf4848484612602565b600e5462010000900460ff16156112795760405162461bcd60e51b815260206004820152601360248201527f4275726e696e672069732064697361626c6564000000000000000000000000006044820152606401610c5d565b61128481600161245a565b50565b60085473ffffffffffffffffffffffffffffffffffffffff1633146112ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600d55565b60085473ffffffffffffffffffffffffffffffffffffffff16331461135a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b805161136d90600a906020840190612ca8565b5050565b6000610a7a8261261d565b600a80546113899061349e565b80601f01602080910402602001604051908101604052809291908181526020018280546113b59061349e565b80156114025780601f106113d757610100808354040283529160200191611402565b820191906000526020600020905b8154815290600101906020018083116113e557829003601f168201915b505050505081565b60085473ffffffffffffffffffffffffffffffffffffffff1633146114715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600c55565b600073ffffffffffffffffffffffffffffffffffffffff82166114c5576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205467ffffffffffffffff1690565b60085473ffffffffffffffffffffffffffffffffffffffff16331461155f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b61156960006126ce565b565b606060038054610a8f9061349e565b60085473ffffffffffffffffffffffffffffffffffffffff1633146115e15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600e8054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b600047600b546116289190613521565b905090565b8161163781611e9d565b610b908383612745565b8373ffffffffffffffffffffffffffffffffffffffff811633146116685761166833611e9d565b611674858585856127dc565b5050505050565b606061168682611e5d565b6116f85760405162461bcd60e51b815260206004820152602160248201527f4552433732314d657461646174613a204e6f6e6578697374656e7420746f6b6560448201527f6e000000000000000000000000000000000000000000000000000000000000006064820152608401610c5d565b6000611702612846565b90506000815111611722576040518060200160405280600081525061174d565b8061172c84612855565b60405160200161173d9291906135a1565b6040516020818303038152906040525b9392505050565b600260095414156117a75760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c5d565b6002600955600e5460ff16156117ff5760405162461bcd60e51b815260206004820152601a60248201527f436c61696d696e6720686173206265656e2064697361626c65640000000000006044820152606401610c5d565b61180a338285610cd2565b6118565760405162461bcd60e51b815260206004820152601160248201527f5369676e617475726520696e76616c69640000000000000000000000000000006044820152606401610c5d565b3360009081526005602052604080822054901c67ffffffffffffffff169061187e82866135d0565b9050600d5481111561188f5750600d545b8084111561189b578093505b600054600c546118ab8683613521565b11156118f95760405162461bcd60e51b815260206004820152601260248201527f45786365656473206d617820737570706c7900000000000000000000000000006044820152606401610c5d565b6111e13386612987565b600080858589868660405160200161191f95949392919061362d565b60405160208183030381529060405280519060200120905060008160405160200161197691907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60405160208183030381529060405280519060200120905073918de5f6a7411219d7ea785dce2d5d6b120b291273ffffffffffffffffffffffffffffffffffffffff166119c3828a6123bd565b73ffffffffffffffffffffffffffffffffffffffff16149998505050505050505050565b600061162860015490565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260408082205467ffffffffffffffff911c16610a7a565b6012546040517fc455279100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260009281169190841690829063c455279190602401602060405180830381865afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac6919061367c565b73ffffffffffffffffffffffffffffffffffffffff161415611aec576001915050610a7a565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526007602090815260408083209387168352929052205460ff165b949350505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314611b925760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b828114611c075760405162461bcd60e51b815260206004820152603360248201527f496e76616c6964207175616e74697469657320616e6420726563697069656e7460448201527f7320286c656e677468206d69736d6174636829000000000000000000000000006064820152608401610c5d565b600080611c1360005490565b905060005b85811015611c5657868682818110611c3257611c32613539565b9050602002013583611c449190613521565b9250611c4f81613568565b9050611c18565b50600c54611c648383613521565b1115611cb25760405162461bcd60e51b815260206004820152601260248201527f45786365656473206d6178206d7570706c7900000000000000000000000000006044820152606401610c5d565b6000915060005b83811015611d1957611d09858583818110611cd657611cd6613539565b9050602002016020810190611ceb9190612ee8565b888884818110611cfd57611cfd613539565b90506020020135612987565b611d1281613568565b9050611cb9565b50505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314611d895760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b73ffffffffffffffffffffffffffffffffffffffff8116611e125760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c5d565b611284816126ce565b60005b8151811015610bf457611e4b8484848481518110611e3e57611e3e613539565b6020026020010151610bc2565b80611e5581613568565b915050611e1e565b6000805482108015610a7a5750506000908152600460205260409020547c0100000000000000000000000000000000000000000000000000000000161590565b6daaeb6d7670e522a718067333cd4e3b15611284576040517fc617113400000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f549190613699565b611284576040517fede71dcc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610c5d565b6000611fad82611371565b90503373ffffffffffffffffffffffffffffffffffffffff82161461200c57611fd68133611a2a565b61200c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b604080516080810182526000808252602082018190529181018290526060810191909152610a7a6120bd8361261d565b6040805160808101825273ffffffffffffffffffffffffffffffffffffffff8316815260a083901c67ffffffffffffffff1660208201527c0100000000000000000000000000000000000000000000000000000000831615159181019190915260e89190911c606082015290565b60006121368261261d565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461219d576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260066020526040902080546121d68187335b73ffffffffffffffffffffffffffffffffffffffff9081169116811491141790565b61221a576121e48633611a2a565b61221a576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516612267576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801561227257600082555b73ffffffffffffffffffffffffffffffffffffffff86811660009081526005602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055918716808252919020805460010190554260a01b177c0200000000000000000000000000000000000000000000000000000000176000858152600460205260409020557c0200000000000000000000000000000000000000000000000000000000831661235a57600184016000818152600460205260409020546123585760005481146123585760008181526004602052604090208490555b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000806000806123cc85612abe565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015612427573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151979650505050505050565b60006124658361261d565b90508060008061248386600090815260066020526040902080549091565b9150915084156124dc576124988184336121b4565b6124dc576124a68333611a2a565b6124dc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80156124e757600082555b73ffffffffffffffffffffffffffffffffffffffff8316600081815260056020526040902080546fffffffffffffffffffffffffffffffff0190554260a01b177c0300000000000000000000000000000000000000000000000000000000176000878152600460205260409020557c020000000000000000000000000000000000000000000000000000000084166125ad57600186016000818152600460205260409020546125ab5760005481146125ab5760008181526004602052604090208590555b505b604051869060009073ffffffffffffffffffffffffffffffffffffffff8616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050600180548101905550505050565b610b9083838360405180602001604052806000815250611641565b60008160005481101561269c576000818152600460205260409020547c0100000000000000000000000000000000000000000000000000000000811661269a575b8061174d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160008181526004602052604090205461265e565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b33600081815260076020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6127e7848484610bc2565b73ffffffffffffffffffffffffffffffffffffffff83163b15610bf45761281084848484612b32565b610bf4576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060600a8054610a8f9061349e565b60608161289557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156128bf57806128a981613568565b91506128b89050600a836136e5565b9150612899565b60008167ffffffffffffffff8111156128da576128da612f05565b6040519080825280601f01601f191660200182016040528015612904576020820181803683370190505b5090505b8415611b23576129196001836135d0565b9150612926600a866136f9565b612931906030613521565b60f81b81838151811061294657612946613539565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612980600a866136e5565b9450612908565b600054816129c1576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612a7d57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612a45565b5081612ab5576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005550505050565b60008060008351604114612b145760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610c5d565b50505060208101516040820151606090920151909260009190911a90565b6040517f150b7a0200000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290612b8d90339089908890889060040161370d565b6020604051808303816000875af1925050508015612be6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612be391810190613756565b60015b612c5a573d808015612c14576040519150601f19603f3d011682016040523d82523d6000602084013e612c19565b606091505b508051612c52576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050949350505050565b828054612cb49061349e565b90600052602060002090601f016020900481019282612cd65760008555612d1c565b82601f10612cef57805160ff1916838001178555612d1c565b82800160010185558215612d1c579182015b82811115612d1c578251825591602001919060010190612d01565b50612d28929150612d2c565b5090565b5b80821115612d285760008155600101612d2d565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461128457600080fd5b600060208284031215612d8157600080fd5b813561174d81612d41565b60005b83811015612da7578181015183820152602001612d8f565b83811115610bf45750506000910152565b60008151808452612dd0816020860160208601612d8c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061174d6020830184612db8565b600060208284031215612e2757600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461128457600080fd5b60008060408385031215612e6357600080fd5b8235612e6e81612e2e565b946020939093013593505050565b600080600060608486031215612e9157600080fd5b8335612e9c81612e2e565b92506020840135612eac81612e2e565b929592945050506040919091013590565b801515811461128457600080fd5b600060208284031215612edd57600080fd5b813561174d81612ebd565b600060208284031215612efa57600080fd5b813561174d81612e2e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f7b57612f7b612f05565b604052919050565b600067ffffffffffffffff831115612f9d57612f9d612f05565b612fce60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601612f34565b9050828152838383011115612fe257600080fd5b828260208301376000602084830101529392505050565b600082601f83011261300a57600080fd5b61174d83833560208501612f83565b60008060006060848603121561302e57600080fd5b833561303981612e2e565b9250602084013567ffffffffffffffff81111561305557600080fd5b61306186828701612ff9565b925050604084013590509250925092565b60008083601f84011261308457600080fd5b50813567ffffffffffffffff81111561309c57600080fd5b6020830191508360208260051b85010111156130b757600080fd5b9250929050565b6000806000806000606086880312156130d657600080fd5b853567ffffffffffffffff808211156130ee57600080fd5b6130fa89838a01613072565b9097509550602088013591508082111561311357600080fd5b61311f89838a01613072565b9095509350604088013591508082111561313857600080fd5b5061314588828901612ff9565b9150509295509295909350565b60006020828403121561316457600080fd5b813567ffffffffffffffff81111561317b57600080fd5b8201601f8101841361318c57600080fd5b611b2384823560208401612f83565b600080604083850312156131ae57600080fd5b82356131b981612e2e565b915060208301356131c981612ebd565b809150509250929050565b600080600080608085870312156131ea57600080fd5b84356131f581612e2e565b9350602085013561320581612e2e565b925060408501359150606085013567ffffffffffffffff81111561322857600080fd5b61323487828801612ff9565b91505092959194509250565b60008060006060848603121561325557600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561327a57600080fd5b61328686828701612ff9565b9150509250925092565b600080600080600080608087890312156132a957600080fd5b86356132b481612e2e565b9550602087013567ffffffffffffffff808211156132d157600080fd5b6132dd8a838b01612ff9565b965060408901359150808211156132f357600080fd5b6132ff8a838b01613072565b9096509450606089013591508082111561331857600080fd5b5061332589828a01613072565b979a9699509497509295939492505050565b6000806040838503121561334a57600080fd5b823561335581612e2e565b915060208301356131c981612e2e565b6000806000806040858703121561337b57600080fd5b843567ffffffffffffffff8082111561339357600080fd5b61339f88838901613072565b909650945060208701359150808211156133b857600080fd5b506133c587828801613072565b95989497509550505050565b6000806000606084860312156133e657600080fd5b83356133f181612e2e565b925060208481013561340281612e2e565b9250604085013567ffffffffffffffff8082111561341f57600080fd5b818701915087601f83011261343357600080fd5b81358181111561344557613445612f05565b8060051b9150613456848301612f34565b818152918301840191848101908a84111561347057600080fd5b938501935b8385101561348e57843582529385019390850190613475565b8096505050505050509250925092565b600181811c908216806134b257607f821691505b602082108114156134ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115613534576135346134f2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561359a5761359a6134f2565b5060010190565b600083516135b3818460208801612d8c565b8351908301906135c7818360208801612d8c565b01949350505050565b6000828210156135e2576135e26134f2565b500390565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561361657600080fd5b8260051b8083863760009401938452509192915050565b600061363a8287896135e7565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681526136706014820185876135e7565b98975050505050505050565b60006020828403121561368e57600080fd5b815161174d81612e2e565b6000602082840312156136ab57600080fd5b815161174d81612ebd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826136f4576136f46136b6565b500490565b600082613708576137086136b6565b500690565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261374c6080830184612db8565b9695505050505050565b60006020828403121561376857600080fd5b815161174d81612d4156fea2646970667358221220d41385961fb5df226d9a25f31d9e1621938c51c5053299c875de1ed2f946764764736f6c634300080a003368747470733a2f2f6d6173746572636174736e66742e696f3a373737372f6170692f746f6b656e732f63617272696572732f
Deployed Bytecode
0x6080604052600436106103345760003560e01c80636c0360eb116101b0578063b88d4fde116100ec578063d89135cd11610095578063f2a452981161006f578063f2a452981461091b578063f2fde38b1461093b578063f3993d111461095b578063fe3dbd811461097b57600080fd5b8063d89135cd146108c6578063dc33e681146108db578063e985e9c5146108fb57600080fd5b8063ce3dc5cf116100c6578063ce3dc5cf14610870578063d50e003614610890578063d5abeb01146108b057600080fd5b8063b88d4fde14610810578063c87b56dd14610823578063cd7c03261461084357600080fd5b80638da5cb5b116101595780639f550293116101335780639f550293146107a7578063a22cb465146107bc578063a2309ff8146107dc578063a7b7f222146107f157600080fd5b80638da5cb5b1461074757806395d89b411461077257806399edf7eb1461078757600080fd5b8063715018a61161018a578063715018a6146107075780637501f7411461071c57806389404a791461073257600080fd5b80636c0360eb146106b25780636f8b44b0146106c757806370a08231146106e757600080fd5b80633ccfd60b1161027f57806342966c6811610228578063547520fe11610202578063547520fe1461062a57806355f804b31461064a578063582abd121461066a5780636352211e1461069257600080fd5b806342966c68146105cc578063468f87f2146105ec5780634b3197131461061457600080fd5b80634193cdf8116102595780634193cdf81461057757806341f434341461059757806342842e0e146105b957600080fd5b80633ccfd60b146105275780633d43675a1461052f5780634121555e1461054f57600080fd5b806318160ddd116102e15780632478d639116102bb5780632478d639146104cd578063285e61d1146104ed57806332b9de9a1461050d57600080fd5b806318160ddd1461048157806323b872dd1461049a57806323d2bf1e146104ad57600080fd5b8063095ea7b311610312578063095ea7b3146103d557806312b58349146103ea578063140364a11461040757600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b50610359610354366004612d6f565b61099b565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610a80565b6040516103659190612e02565b34801561039c57600080fd5b506103b06103ab366004612e15565b610b12565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610365565b6103e86103e3366004612e50565b610b7c565b005b3480156103f657600080fd5b50475b604051908152602001610365565b34801561041357600080fd5b50610427610422366004612e15565b610b95565b6040516103659190815173ffffffffffffffffffffffffffffffffffffffff16815260208083015167ffffffffffffffff169082015260408083015115159082015260609182015162ffffff169181019190915260800190565b34801561048d57600080fd5b50600154600054036103f9565b6103e86104a8366004612e7c565b610bc2565b3480156104b957600080fd5b506103e86104c8366004612ecb565b610bfa565b3480156104d957600080fd5b506103f96104e8366004612ee8565b610c97565b3480156104f957600080fd5b50610359610508366004613019565b610cd2565b34801561051957600080fd5b50600e546103599060ff1681565b6103e8610dd5565b34801561053b57600080fd5b506103e861054a366004612ecb565b610eae565b34801561055b57600080fd5b506103b0737d0b3f2f241caede2d6d885bb6d7f149ecdfba2481565b34801561058357600080fd5b506103e86105923660046130be565b610f4d565b3480156105a357600080fd5b506103b06daaeb6d7670e522a718067333cd4e81565b6103e86105c7366004612e7c565b6111ee565b3480156105d857600080fd5b506103e86105e7366004612e15565b611220565b3480156105f857600080fd5b506103b073f03c4e6b6187aca96b18162cbb4468fc6e33912081565b34801561062057600080fd5b506103f9600b5481565b34801561063657600080fd5b506103e8610645366004612e15565b611287565b34801561065657600080fd5b506103e8610665366004613152565b6112f3565b34801561067657600080fd5b506103b073918de5f6a7411219d7ea785dce2d5d6b120b291281565b34801561069e57600080fd5b506103b06106ad366004612e15565b611371565b3480156106be57600080fd5b5061038361137c565b3480156106d357600080fd5b506103e86106e2366004612e15565b61140a565b3480156106f357600080fd5b506103f9610702366004612ee8565b611476565b34801561071357600080fd5b506103e86114f8565b34801561072857600080fd5b506103f9600d5481565b34801561073e57600080fd5b50600b546103f9565b34801561075357600080fd5b5060085473ffffffffffffffffffffffffffffffffffffffff166103b0565b34801561077e57600080fd5b5061038361156b565b34801561079357600080fd5b506103e86107a2366004612ecb565b61157a565b3480156107b357600080fd5b506103f9611618565b3480156107c857600080fd5b506103e86107d736600461319b565b61162d565b3480156107e857600080fd5b506000546103f9565b3480156107fd57600080fd5b50600e5461035990610100900460ff1681565b6103e861081e3660046131d4565b611641565b34801561082f57600080fd5b5061038361083e366004612e15565b61167b565b34801561084f57600080fd5b506012546103b09073ffffffffffffffffffffffffffffffffffffffff1681565b34801561087c57600080fd5b506103e861088b366004613240565b611754565b34801561089c57600080fd5b506103596108ab366004613290565b611903565b3480156108bc57600080fd5b506103f9600c5481565b3480156108d257600080fd5b506103f96119e7565b3480156108e757600080fd5b506103f96108f6366004612ee8565b6119f2565b34801561090757600080fd5b50610359610916366004613337565b611a2a565b34801561092757600080fd5b506103e8610936366004613365565b611b2b565b34801561094757600080fd5b506103e8610956366004612ee8565b611d22565b34801561096757600080fd5b506103e86109763660046133d1565b611e1b565b34801561098757600080fd5b50600e546103599062010000900460ff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161480610a2e57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b80610a7a57507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b606060028054610a8f9061349e565b80601f0160208091040260200160405190810160405280929190818152602001828054610abb9061349e565b8015610b085780601f10610add57610100808354040283529160200191610b08565b820191906000526020600020905b815481529060010190602001808311610aeb57829003601f168201915b5050505050905090565b6000610b1d82611e5d565b610b53576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060009081526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b81610b8681611e9d565b610b908383611fa2565b505050565b604080516080810182526000808252602082018190529181018290526060810191909152610a7a8261208d565b8273ffffffffffffffffffffffffffffffffffffffff81163314610be957610be933611e9d565b610bf484848461212b565b50505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610c665760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6000610a7a8273ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205460801c67ffffffffffffffff1690565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018290526000908190605401604051602081830303815290604052805190602001209050600081604051602001610d6791907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60405160208183030381529060405280519060200120905073918de5f6a7411219d7ea785dce2d5d6b120b291273ffffffffffffffffffffffffffffffffffffffff16610db482876123bd565b73ffffffffffffffffffffffffffffffffffffffff16149695505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610e3c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b6040514790600090339083908381818185875af1925050503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5050905080610e9357600080fd5b81600b6000828254610ea59190613521565b90915550505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610f155760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600e805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b60026009541415610fa05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c5d565b6002600955600e54610100900460ff1615610ffd5760405162461bcd60e51b815260206004820152601b60248201527f52656465656d696e6720686173206265656e2064697361626c656400000000006044820152606401610c5d565b8382146110725760405162461bcd60e51b815260206004820152602f60248201527f496e76616c6964206361727269657249647320616e642063617449647320286c60448201527f656e677468206d69736d617463682900000000000000000000000000000000006064820152608401610c5d565b611080338287878787611903565b6110cc5760405162461bcd60e51b815260206004820152601160248201527f5369676e617475726520696e76616c69640000000000000000000000000000006044820152606401610c5d565b60005b848110156111e1576110fa8686838181106110ec576110ec613539565b90506020020135600161245a565b73f03c4e6b6187aca96b18162cbb4468fc6e3391206342842e0e737d0b3f2f241caede2d6d885bb6d7f149ecdfba243387878681811061113c5761113c613539565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815273ffffffffffffffffffffffffffffffffffffffff958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b1580156111b857600080fd5b505af11580156111cc573d6000803e3d6000fd5b50505050806111da90613568565b90506110cf565b5050600160095550505050565b8273ffffffffffffffffffffffffffffffffffffffff811633146112155761121533611e9d565b610bf4848484612602565b600e5462010000900460ff16156112795760405162461bcd60e51b815260206004820152601360248201527f4275726e696e672069732064697361626c6564000000000000000000000000006044820152606401610c5d565b61128481600161245a565b50565b60085473ffffffffffffffffffffffffffffffffffffffff1633146112ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600d55565b60085473ffffffffffffffffffffffffffffffffffffffff16331461135a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b805161136d90600a906020840190612ca8565b5050565b6000610a7a8261261d565b600a80546113899061349e565b80601f01602080910402602001604051908101604052809291908181526020018280546113b59061349e565b80156114025780601f106113d757610100808354040283529160200191611402565b820191906000526020600020905b8154815290600101906020018083116113e557829003601f168201915b505050505081565b60085473ffffffffffffffffffffffffffffffffffffffff1633146114715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600c55565b600073ffffffffffffffffffffffffffffffffffffffff82166114c5576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205467ffffffffffffffff1690565b60085473ffffffffffffffffffffffffffffffffffffffff16331461155f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b61156960006126ce565b565b606060038054610a8f9061349e565b60085473ffffffffffffffffffffffffffffffffffffffff1633146115e15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600e8054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b600047600b546116289190613521565b905090565b8161163781611e9d565b610b908383612745565b8373ffffffffffffffffffffffffffffffffffffffff811633146116685761166833611e9d565b611674858585856127dc565b5050505050565b606061168682611e5d565b6116f85760405162461bcd60e51b815260206004820152602160248201527f4552433732314d657461646174613a204e6f6e6578697374656e7420746f6b6560448201527f6e000000000000000000000000000000000000000000000000000000000000006064820152608401610c5d565b6000611702612846565b90506000815111611722576040518060200160405280600081525061174d565b8061172c84612855565b60405160200161173d9291906135a1565b6040516020818303038152906040525b9392505050565b600260095414156117a75760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c5d565b6002600955600e5460ff16156117ff5760405162461bcd60e51b815260206004820152601a60248201527f436c61696d696e6720686173206265656e2064697361626c65640000000000006044820152606401610c5d565b61180a338285610cd2565b6118565760405162461bcd60e51b815260206004820152601160248201527f5369676e617475726520696e76616c69640000000000000000000000000000006044820152606401610c5d565b3360009081526005602052604080822054901c67ffffffffffffffff169061187e82866135d0565b9050600d5481111561188f5750600d545b8084111561189b578093505b600054600c546118ab8683613521565b11156118f95760405162461bcd60e51b815260206004820152601260248201527f45786365656473206d617820737570706c7900000000000000000000000000006044820152606401610c5d565b6111e13386612987565b600080858589868660405160200161191f95949392919061362d565b60405160208183030381529060405280519060200120905060008160405160200161197691907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60405160208183030381529060405280519060200120905073918de5f6a7411219d7ea785dce2d5d6b120b291273ffffffffffffffffffffffffffffffffffffffff166119c3828a6123bd565b73ffffffffffffffffffffffffffffffffffffffff16149998505050505050505050565b600061162860015490565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260408082205467ffffffffffffffff911c16610a7a565b6012546040517fc455279100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260009281169190841690829063c455279190602401602060405180830381865afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac6919061367c565b73ffffffffffffffffffffffffffffffffffffffff161415611aec576001915050610a7a565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526007602090815260408083209387168352929052205460ff165b949350505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314611b925760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b828114611c075760405162461bcd60e51b815260206004820152603360248201527f496e76616c6964207175616e74697469657320616e6420726563697069656e7460448201527f7320286c656e677468206d69736d6174636829000000000000000000000000006064820152608401610c5d565b600080611c1360005490565b905060005b85811015611c5657868682818110611c3257611c32613539565b9050602002013583611c449190613521565b9250611c4f81613568565b9050611c18565b50600c54611c648383613521565b1115611cb25760405162461bcd60e51b815260206004820152601260248201527f45786365656473206d6178206d7570706c7900000000000000000000000000006044820152606401610c5d565b6000915060005b83811015611d1957611d09858583818110611cd657611cd6613539565b9050602002016020810190611ceb9190612ee8565b888884818110611cfd57611cfd613539565b90506020020135612987565b611d1281613568565b9050611cb9565b50505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314611d895760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b73ffffffffffffffffffffffffffffffffffffffff8116611e125760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c5d565b611284816126ce565b60005b8151811015610bf457611e4b8484848481518110611e3e57611e3e613539565b6020026020010151610bc2565b80611e5581613568565b915050611e1e565b6000805482108015610a7a5750506000908152600460205260409020547c0100000000000000000000000000000000000000000000000000000000161590565b6daaeb6d7670e522a718067333cd4e3b15611284576040517fc617113400000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f549190613699565b611284576040517fede71dcc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610c5d565b6000611fad82611371565b90503373ffffffffffffffffffffffffffffffffffffffff82161461200c57611fd68133611a2a565b61200c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b604080516080810182526000808252602082018190529181018290526060810191909152610a7a6120bd8361261d565b6040805160808101825273ffffffffffffffffffffffffffffffffffffffff8316815260a083901c67ffffffffffffffff1660208201527c0100000000000000000000000000000000000000000000000000000000831615159181019190915260e89190911c606082015290565b60006121368261261d565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461219d576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260066020526040902080546121d68187335b73ffffffffffffffffffffffffffffffffffffffff9081169116811491141790565b61221a576121e48633611a2a565b61221a576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516612267576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801561227257600082555b73ffffffffffffffffffffffffffffffffffffffff86811660009081526005602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055918716808252919020805460010190554260a01b177c0200000000000000000000000000000000000000000000000000000000176000858152600460205260409020557c0200000000000000000000000000000000000000000000000000000000831661235a57600184016000818152600460205260409020546123585760005481146123585760008181526004602052604090208490555b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000806000806123cc85612abe565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015612427573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151979650505050505050565b60006124658361261d565b90508060008061248386600090815260066020526040902080549091565b9150915084156124dc576124988184336121b4565b6124dc576124a68333611a2a565b6124dc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80156124e757600082555b73ffffffffffffffffffffffffffffffffffffffff8316600081815260056020526040902080546fffffffffffffffffffffffffffffffff0190554260a01b177c0300000000000000000000000000000000000000000000000000000000176000878152600460205260409020557c020000000000000000000000000000000000000000000000000000000084166125ad57600186016000818152600460205260409020546125ab5760005481146125ab5760008181526004602052604090208590555b505b604051869060009073ffffffffffffffffffffffffffffffffffffffff8616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050600180548101905550505050565b610b9083838360405180602001604052806000815250611641565b60008160005481101561269c576000818152600460205260409020547c0100000000000000000000000000000000000000000000000000000000811661269a575b8061174d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160008181526004602052604090205461265e565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b33600081815260076020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6127e7848484610bc2565b73ffffffffffffffffffffffffffffffffffffffff83163b15610bf45761281084848484612b32565b610bf4576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060600a8054610a8f9061349e565b60608161289557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156128bf57806128a981613568565b91506128b89050600a836136e5565b9150612899565b60008167ffffffffffffffff8111156128da576128da612f05565b6040519080825280601f01601f191660200182016040528015612904576020820181803683370190505b5090505b8415611b23576129196001836135d0565b9150612926600a866136f9565b612931906030613521565b60f81b81838151811061294657612946613539565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612980600a866136e5565b9450612908565b600054816129c1576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612a7d57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612a45565b5081612ab5576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005550505050565b60008060008351604114612b145760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610c5d565b50505060208101516040820151606090920151909260009190911a90565b6040517f150b7a0200000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290612b8d90339089908890889060040161370d565b6020604051808303816000875af1925050508015612be6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612be391810190613756565b60015b612c5a573d808015612c14576040519150601f19603f3d011682016040523d82523d6000602084013e612c19565b606091505b508051612c52576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050949350505050565b828054612cb49061349e565b90600052602060002090601f016020900481019282612cd65760008555612d1c565b82601f10612cef57805160ff1916838001178555612d1c565b82800160010185558215612d1c579182015b82811115612d1c578251825591602001919060010190612d01565b50612d28929150612d2c565b5090565b5b80821115612d285760008155600101612d2d565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461128457600080fd5b600060208284031215612d8157600080fd5b813561174d81612d41565b60005b83811015612da7578181015183820152602001612d8f565b83811115610bf45750506000910152565b60008151808452612dd0816020860160208601612d8c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061174d6020830184612db8565b600060208284031215612e2757600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461128457600080fd5b60008060408385031215612e6357600080fd5b8235612e6e81612e2e565b946020939093013593505050565b600080600060608486031215612e9157600080fd5b8335612e9c81612e2e565b92506020840135612eac81612e2e565b929592945050506040919091013590565b801515811461128457600080fd5b600060208284031215612edd57600080fd5b813561174d81612ebd565b600060208284031215612efa57600080fd5b813561174d81612e2e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f7b57612f7b612f05565b604052919050565b600067ffffffffffffffff831115612f9d57612f9d612f05565b612fce60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601612f34565b9050828152838383011115612fe257600080fd5b828260208301376000602084830101529392505050565b600082601f83011261300a57600080fd5b61174d83833560208501612f83565b60008060006060848603121561302e57600080fd5b833561303981612e2e565b9250602084013567ffffffffffffffff81111561305557600080fd5b61306186828701612ff9565b925050604084013590509250925092565b60008083601f84011261308457600080fd5b50813567ffffffffffffffff81111561309c57600080fd5b6020830191508360208260051b85010111156130b757600080fd5b9250929050565b6000806000806000606086880312156130d657600080fd5b853567ffffffffffffffff808211156130ee57600080fd5b6130fa89838a01613072565b9097509550602088013591508082111561311357600080fd5b61311f89838a01613072565b9095509350604088013591508082111561313857600080fd5b5061314588828901612ff9565b9150509295509295909350565b60006020828403121561316457600080fd5b813567ffffffffffffffff81111561317b57600080fd5b8201601f8101841361318c57600080fd5b611b2384823560208401612f83565b600080604083850312156131ae57600080fd5b82356131b981612e2e565b915060208301356131c981612ebd565b809150509250929050565b600080600080608085870312156131ea57600080fd5b84356131f581612e2e565b9350602085013561320581612e2e565b925060408501359150606085013567ffffffffffffffff81111561322857600080fd5b61323487828801612ff9565b91505092959194509250565b60008060006060848603121561325557600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561327a57600080fd5b61328686828701612ff9565b9150509250925092565b600080600080600080608087890312156132a957600080fd5b86356132b481612e2e565b9550602087013567ffffffffffffffff808211156132d157600080fd5b6132dd8a838b01612ff9565b965060408901359150808211156132f357600080fd5b6132ff8a838b01613072565b9096509450606089013591508082111561331857600080fd5b5061332589828a01613072565b979a9699509497509295939492505050565b6000806040838503121561334a57600080fd5b823561335581612e2e565b915060208301356131c981612e2e565b6000806000806040858703121561337b57600080fd5b843567ffffffffffffffff8082111561339357600080fd5b61339f88838901613072565b909650945060208701359150808211156133b857600080fd5b506133c587828801613072565b95989497509550505050565b6000806000606084860312156133e657600080fd5b83356133f181612e2e565b925060208481013561340281612e2e565b9250604085013567ffffffffffffffff8082111561341f57600080fd5b818701915087601f83011261343357600080fd5b81358181111561344557613445612f05565b8060051b9150613456848301612f34565b818152918301840191848101908a84111561347057600080fd5b938501935b8385101561348e57843582529385019390850190613475565b8096505050505050509250925092565b600181811c908216806134b257607f821691505b602082108114156134ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115613534576135346134f2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561359a5761359a6134f2565b5060010190565b600083516135b3818460208801612d8c565b8351908301906135c7818360208801612d8c565b01949350505050565b6000828210156135e2576135e26134f2565b500390565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561361657600080fd5b8260051b8083863760009401938452509192915050565b600061363a8287896135e7565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681526136706014820185876135e7565b98975050505050505050565b60006020828403121561368e57600080fd5b815161174d81612e2e565b6000602082840312156136ab57600080fd5b815161174d81612ebd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826136f4576136f46136b6565b500490565b600082613708576137086136b6565b500690565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261374c6080830184612db8565b9695505050505050565b60006020828403121561376857600080fd5b815161174d81612d4156fea2646970667358221220d41385961fb5df226d9a25f31d9e1621938c51c5053299c875de1ed2f946764764736f6c634300080a0033
Deployed Bytecode Sourcemap
546:9627:16:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9410:639:4;;;;;;;;;;-1:-1:-1;9410:639:4;;;;;:::i;:::-;;:::i;:::-;;;611:14:21;;604:22;586:41;;574:2;559:18;9410:639:4;;;;;;;;10312:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16803:218::-;;;;;;;;;;-1:-1:-1;16803:218:4;;;;;:::i;:::-;;:::i;:::-;;;1809:42:21;1797:55;;;1779:74;;1767:2;1752:18;16803:218:4;1633:226:21;1808:165:16;;;;;;:::i;:::-;;:::i;:::-;;9071:104;;;;;;;;;;-1:-1:-1;9146:21:16;9071:104;;;2489:25:21;;;2477:2;2462:18;9071:104:16;2343:177:21;8793:163:16;;;;;;;;;;-1:-1:-1;8793:163:16;;;;;:::i;:::-;;:::i;:::-;;;;;;2758:13:21;;2773:42;2754:62;2736:81;;2877:4;2865:17;;;2859:24;2885:18;2855:49;2833:20;;;2826:79;2975:4;2963:17;;;2957:24;2950:32;2943:40;2921:20;;;2914:70;3044:4;3032:17;;;3026:24;3052:8;3022:39;3000:20;;;2993:69;;;;2723:3;2708:19;;2525:543;6063:323:4;;;;;;;;;;-1:-1:-1;6337:12:4;;6124:7;6321:13;:28;6063:323;;1981:171:16;;;;;;:::i;:::-;;:::i;7950:125::-;;;;;;;;;;-1:-1:-1;7950:125:16;;;;;:::i;:::-;;:::i;8672:113::-;;;;;;;;;;-1:-1:-1;8672:113:16;;;;;:::i;:::-;;:::i;3233:404::-;;;;;;;;;;-1:-1:-1;3233:404:16;;;;;:::i;:::-;;:::i;841:36::-;;;;;;;;;;-1:-1:-1;841:36:16;;;;;;;;9394:273;;;:::i;8220:121::-;;;;;;;;;;-1:-1:-1;8220:121:16;;;;;:::i;:::-;;:::i;1065:85::-;;;;;;;;;;;;1108:42;1065:85;;4169:764;;;;;;;;;;-1:-1:-1;4169:764:16;;;;;:::i;:::-;;:::i;752:143:17:-;;;;;;;;;;;;852:42;752:143;;2160:179:16;;;;;;:::i;:::-;;:::i;6772:153::-;;;;;;;;;;-1:-1:-1;6772:153:16;;;;;:::i;:::-;;:::i;970:88::-;;;;;;;;;;;;1016:42;970:88;;706:33;;;;;;;;;;;;;;;;7624:92;;;;;;;;;;-1:-1:-1;7624:92:16;;;;;:::i;:::-;;:::i;7838:104::-;;;;;;;;;;-1:-1:-1;7838:104:16;;;;;:::i;:::-;;:::i;1157:75::-;;;;;;;;;;;;1190:42;1157:75;;11705:152:4;;;;;;;;;;-1:-1:-1;11705:152:4;;;;;:::i;:::-;;:::i;678:21:16:-;;;;;;;;;;;;;:::i;7724:106::-;;;;;;;;;;-1:-1:-1;7724:106:16;;;;;:::i;:::-;;:::i;7247:233:4:-;;;;;;;;;;-1:-1:-1;7247:233:4;;;;;:::i;:::-;;:::i;1661:101:18:-;;;;;;;;;;;;;:::i;784:27:16:-;;;;;;;;;;;;;;;;8964:99;;;;;;;;;;-1:-1:-1;9041:14:16;;8964:99;;1029:85:18;;;;;;;;;;-1:-1:-1;1101:6:18;;;;1029:85;;10488:104:4;;;;;;;;;;;;;:::i;8083:129:16:-;;;;;;;;;;-1:-1:-1;8083:129:16;;;;;:::i;:::-;;:::i;9183:121::-;;;;;;;;;;;;;:::i;1624:176::-;;;;;;;;;;-1:-1:-1;1624:176:16;;;;;:::i;:::-;;:::i;8349:93::-;;;;;;;;;;-1:-1:-1;8393:7:16;6730:13:4;8349:93:16;9183:121;884:36;;;;;;;;;;-1:-1:-1;884:36:16;;;;;;;;;;;2347:245;;;;;;:::i;:::-;;:::i;7277:339::-;;;;;;;;;;-1:-1:-1;7277:339:16;;;;;:::i;:::-;;:::i;1400:80::-;;;;;;;;;;-1:-1:-1;1400:80:16;;;;;;;;4995:1040;;;;;;;;;;-1:-1:-1;4995:1040:16;;;;;:::i;:::-;;:::i;3645:439::-;;;;;;;;;;-1:-1:-1;3645:439:16;;;;;:::i;:::-;;:::i;746:31::-;;;;;;;;;;;;;;;;8571:93;;;;;;;;;;;;;:::i;8450:113::-;;;;;;;;;;-1:-1:-1;8450:113:16;;;;;:::i;:::-;;:::i;9768:402::-;;;;;;;;;;-1:-1:-1;9768:402:16;;;;;:::i;:::-;;:::i;6065:699::-;;;;;;;;;;-1:-1:-1;6065:699:16;;;;;:::i;:::-;;:::i;1911:198:18:-;;;;;;;;;;-1:-1:-1;1911:198:18;;;;;:::i;:::-;;:::i;6933:220:16:-;;;;;;;;;;-1:-1:-1;6933:220:16;;;;;:::i;:::-;;:::i;927:34::-;;;;;;;;;;-1:-1:-1;927:34:16;;;;;;;;;;;9410:639:4;9495:4;9819:25;;;;;;:102;;-1:-1:-1;9896:25:4;;;;;9819:102;:179;;;-1:-1:-1;9973:25:4;;;;;9819:179;9799:199;9410:639;-1:-1:-1;;9410:639:4:o;10312:100::-;10366:13;10399:5;10392:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10312:100;:::o;16803:218::-;16879:7;16904:16;16912:7;16904;:16::i;:::-;16899:64;;16929:34;;;;;;;;;;;;;;16899:64;-1:-1:-1;16983:24:4;;;;:15;:24;;;;;:30;;;;16803:218::o;1808:165:16:-;1912:8;2273:30:17;2294:8;2273:20;:30::i;:::-;1933:32:16::1;1947:8;1957:7;1933:13;:32::i;:::-;1808:165:::0;;;:::o;8793:163::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8927:21:16;8940:7;8927:12;:21::i;1981:171::-;2090:4;2093:18:17;;;2101:10;2093:18;2089:83;;2128:32;2149:10;2128:20;:32::i;:::-;2107:37:16::1;2126:4;2132:2;2136:7;2107:18;:37::i;:::-;1981:171:::0;;;;:::o;7950:125::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;;;;;;;;;8031:16:16::1;:36:::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;7950:125::o;8672:113::-;8730:7;8757:20;8771:5;7927:25:4;;7899:7;7927:25;;;:18;:25;;;;;;1671:3;7927:50;1406:13;7926:82;;7838:178;3233:404:16;3396:40;;13993:66:21;13980:2;13976:15;;;13972:88;3396:40:16;;;13960:101:21;14077:12;;;14070:28;;;3347:4:16;;;;14114:12:21;;3396:40:16;;;;;;;;;;;;3386:51;;;;;;3364:73;;3448:28;3542:11;3489:65;;;;;;;14379:66:21;14367:79;;14471:2;14462:12;;14455:28;;;;14508:2;14499:12;;14137:380;3489:65:16;;;;;;;;;;;;;3479:76;;;;;;3448:107;;1190:42;3573:56;;:46;3587:20;3609:9;3573:13;:46::i;:::-;:56;;;;3233:404;-1:-1:-1;;;;;;3233:404:16:o;9394:273::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;9515:64:16::1;::::0;9464:21:::1;::::0;9450:11:::1;::::0;9523:10:::1;::::0;9464:21;;9450:11;9515:64;9450:11;9515:64;9464:21;9523:10;9515:64:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9496:83;;;9598:7;9590:16;;;::::0;::::1;;9635:3;9617:14;;:21;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;9394:273:16:o;8220:121::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;8299:15:16::1;:34:::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;8220:121::o;4169:764::-;1744:1:19;2325:7;;:19;;2317:63;;;;-1:-1:-1;;;2317:63:19;;15256:2:21;2317:63:19;;;15238:21:21;15295:2;15275:18;;;15268:30;15334:33;15314:18;;;15307:61;15385:18;;2317:63:19;15054:355:21;2317:63:19;1744:1;2455:7;:18;4316:17:16::1;::::0;::::1;::::0;::::1;;;4315:18;4307:58;;;::::0;-1:-1:-1;;;4307:58:16;;15616:2:21;4307:58:16::1;::::0;::::1;15598:21:21::0;15655:2;15635:18;;;15628:30;15694:29;15674:18;;;15667:57;15741:18;;4307:58:16::1;15414:351:21::0;4307:58:16::1;4384:34:::0;;::::1;4376:94;;;::::0;-1:-1:-1;;;4376:94:16;;15972:2:21;4376:94:16::1;::::0;::::1;15954:21:21::0;16011:2;15991:18;;;15984:30;16050:34;16030:18;;;16023:62;16121:17;16101:18;;;16094:45;16156:19;;4376:94:16::1;15770:411:21::0;4376:94:16::1;4489:63;4510:10;4522:9;4533:10;;4545:6;;4489:20;:63::i;:::-;4481:93;;;::::0;-1:-1:-1;;;4481:93:16;;16388:2:21;4481:93:16::1;::::0;::::1;16370:21:21::0;16427:2;16407:18;;;16400:30;16466:19;16446:18;;;16439:47;16503:18;;4481:93:16::1;16186:341:21::0;4481:93:16::1;4623:9;4619:307;4638:21:::0;;::::1;4619:307;;;4681:26;4687:10;;4698:1;4687:13;;;;;;;:::i;:::-;;;;;;;4702:4;4681:5;:26::i;:::-;1016:42;4780:46;1108:42;4845:10;4857:6:::0;;4864:1;4857:9;;::::1;;;;;:::i;:::-;4780:87;::::0;;::::1;::::0;;;;;;16933:42:21;17002:15;;;4780:87:16::1;::::0;::::1;16984:34:21::0;17054:15;;;;17034:18;;;17027:43;-1:-1:-1;4857:9:16::1;::::0;;::::1;;;17086:18:21::0;;;17079:34;16896:18;;4780:87:16::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;4661:3;;;;:::i;:::-;;;4619:307;;;-1:-1:-1::0;;1701:1:19;2628:7;:22;-1:-1:-1;;;;4169:764:16:o;2160:179::-;2273:4;2093:18:17;;;2101:10;2093:18;2089:83;;2128:32;2149:10;2128:20;:32::i;:::-;2290:41:16::1;2313:4;2319:2;2323:7;2290:22;:41::i;6772:153::-:0;6847:15;;;;;;;6846:16;6838:48;;;;-1:-1:-1;;;6838:48:16;;17526:2:21;6838:48:16;;;17508:21:21;17565:2;17545:18;;;17538:30;17604:21;17584:18;;;17577:49;17643:18;;6838:48:16;17324:343:21;6838:48:16;6897:20;6903:7;6912:4;6897:5;:20::i;:::-;6772:153;:::o;7624:92::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;7690:7:16::1;:18:::0;7624:92::o;7838:104::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;7913:21:16;;::::1;::::0;:7:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;:::-;;7838:104:::0;:::o;11705:152:4:-;11777:7;11820:27;11839:7;11820:18;:27::i;678:21:16:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7724:106::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;7797:9:16::1;:25:::0;7724:106::o;7247:233:4:-;7319:7;7343:19;;;7339:60;;7371:28;;;;;;;;;;;;;;7339:60;-1:-1:-1;7417:25:4;;;;;;:18;:25;;;;;;1406:13;7417:55;;7247:233::o;1661:101:18:-;1101:6;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;1725:30:::1;1752:1;1725:18;:30::i;:::-;1661:101::o:0;10488:104:4:-;10544:13;10577:7;10570:14;;;;;:::i;8083:129:16:-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;8166:17:16::1;:38:::0;;;::::1;;;;::::0;;;::::1;::::0;;;::::1;::::0;;8083:129::o;9183:121::-;9230:7;9146:21;9041:14;;9257:39;;;;:::i;:::-;9250:46;;9183:121;:::o;1624:176::-;1728:8;2273:30:17;2294:8;2273:20;:30::i;:::-;1749:43:16::1;1773:8;1783;1749:23;:43::i;2347:245::-:0;2515:4;2093:18:17;;;2101:10;2093:18;2089:83;;2128:32;2149:10;2128:20;:32::i;:::-;2537:47:16::1;2560:4;2566:2;2570:7;2579:4;2537:22;:47::i;:::-;2347:245:::0;;;;;:::o;7277:339::-;7350:13;7384:16;7392:7;7384;:16::i;:::-;7376:62;;;;-1:-1:-1;;;7376:62:16;;17874:2:21;7376:62:16;;;17856:21:21;17913:2;17893:18;;;17886:30;17952:34;17932:18;;;17925:62;18023:3;18003:18;;;17996:31;18044:19;;7376:62:16;17672:397:21;7376:62:16;7449:28;7480:10;:8;:10::i;:::-;7449:41;;7539:1;7514:14;7508:28;:32;:100;;;;;;;;;;;;;;;;;7567:14;7583:18;:7;:16;:18::i;:::-;7550:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;7508:100;7501:107;7277:339;-1:-1:-1;;;7277:339:16:o;4995:1040::-;1744:1:19;2325:7;;:19;;2317:63;;;;-1:-1:-1;;;2317:63:19;;15256:2:21;2317:63:19;;;15238:21:21;15295:2;15275:18;;;15268:30;15334:33;15314:18;;;15307:61;15385:18;;2317:63:19;15054:355:21;2317:63:19;1744:1;2455:7;:18;5127:16:16::1;::::0;::::1;;5126:17;5118:56;;;::::0;-1:-1:-1;;;5118:56:16;;18751:2:21;5118:56:16::1;::::0;::::1;18733:21:21::0;18790:2;18770:18;;;18763:30;18829:28;18809:18;;;18802:56;18875:18;;5118:56:16::1;18549:350:21::0;5118:56:16::1;5193:60;5213:10;5225:9;5236:16;5193:19;:60::i;:::-;5185:90;;;::::0;-1:-1:-1;;;5185:90:16;;16388:2:21;5185:90:16::1;::::0;::::1;16370:21:21::0;16427:2;16407:18;;;16400:30;16466:19;16446:18;;;16439:47;16503:18;;5185:90:16::1;16186:341:21::0;5185:90:16::1;5349:10;5314:18;7651:25:4::0;;;:18;:25;;1544:2;7651:25;;;;:50;;1406:13;7650:82;;5416:29:16::1;7650:82:4::0;5416:16:16;:29:::1;:::i;:::-;5394:51;;5583:7;;5569:11;:21;5566:74;;;-1:-1:-1::0;5621:7:16::1;::::0;5566:74:::1;5706:11;5695:8;:22;5692:76;;;5745:11;5734:22;;5692:76;5778:14;6730:13:4::0;5876:9:16::1;::::0;5854:17:::1;5863:8:::0;6730:13:4;5854:17:16::1;:::i;:::-;5853:32;;5845:63;;;::::0;-1:-1:-1;;;5845:63:16;;19236:2:21;5845:63:16::1;::::0;::::1;19218:21:21::0;19275:2;19255:18;;;19248:30;19314:20;19294:18;;;19287:48;19352:18;;5845:63:16::1;19034:342:21::0;5845:63:16::1;5919:27;5925:10;5937:8;5919:5;:27::i;3645:439::-:0;3792:4;3809:19;3858:10;;3870:4;3876:6;;3841:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3831:53;;;;;;3809:75;;3895:28;3989:11;3936:65;;;;;;;14379:66:21;14367:79;;14471:2;14462:12;;14455:28;;;;14508:2;14499:12;;14137:380;3936:65:16;;;;;;;;;;;;;3926:76;;;;;;3895:107;;1190:42;4020:56;;:46;4034:20;4056:9;4020:13;:46::i;:::-;:56;;;;3645:439;-1:-1:-1;;;;;;;;;3645:439:16:o;8571:93::-;8615:7;8642:14;6944:12:4;;;6862:102;8450:113:16;7651:25:4;;;8508:7:16;7651:25:4;;;:18;:25;;1544:2;7651:25;;;;1406:13;7651:50;;7650:82;8535:20:16;7562:178:4;9768:402:16;9981:20;;10025:28;;;;;9981:20;1797:55:21;;;10025:28:16;;;1779:74:21;9857:4:16;;9981:20;;;10017:49;;;;9981:20;;10025:21;;1752:18:21;;10025:28:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10017:49;;;10013:93;;;10090:4;10083:11;;;;;10013:93;17873:25:4;;;;17849:4;17873:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;10123:39:16;10116:46;9768:402;-1:-1:-1;;;;9768:402:16:o;6065:699::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;6192:38:16;;::::1;6184:102;;;::::0;-1:-1:-1;;;6184:102:16;;20808:2:21;6184:102:16::1;::::0;::::1;20790:21:21::0;20847:2;20827:18;;;20820:30;20886:34;20866:18;;;20859:62;20957:21;20937:18;;;20930:49;20996:19;;6184:102:16::1;20606:415:21::0;6184:102:16::1;6297:21;6333:14:::0;6350::::1;6539:7:4::0;6730:13;;6484:296;6350:14:16::1;6333:31;;6405:9;6400:105;6420:21:::0;;::::1;6400:105;;;6480:10;;6491:1;6480:13;;;;;;;:::i;:::-;;;;;;;6463:30;;;;;:::i;:::-;::::0;-1:-1:-1;6443:3:16::1;::::0;::::1;:::i;:::-;;;6400:105;;;-1:-1:-1::0;6549:9:16::1;::::0;6523:22:::1;6532:13:::0;6523:6;:22:::1;:::i;:::-;:35;;6515:66;;;::::0;-1:-1:-1;;;6515:66:16;;21228:2:21;6515:66:16::1;::::0;::::1;21210:21:21::0;21267:2;21247:18;;;21240:30;21306:20;21286:18;;;21279:48;21344:18;;6515:66:16::1;21026:342:21::0;6515:66:16::1;6592:20;;;6628:9;6623:110;6643:21:::0;;::::1;6623:110;;;6686:35;6692:10;;6703:1;6692:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;6707:10;;6718:1;6707:13;;;;;;;:::i;:::-;;;;;;;6686:5;:35::i;:::-;6666:3;::::0;::::1;:::i;:::-;;;6623:110;;;-1:-1:-1::0;;;;;;;6065:699:16:o;1911:198:18:-;1101:6;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;1999:22:::1;::::0;::::1;1991:73;;;::::0;-1:-1:-1;;;1991:73:18;;21575:2:21;1991:73:18::1;::::0;::::1;21557:21:21::0;21614:2;21594:18;;;21587:30;21653:34;21633:18;;;21626:62;21724:8;21704:18;;;21697:36;21750:19;;1991:73:18::1;21373:402:21::0;1991:73:18::1;2074:28;2093:8;2074:18;:28::i;6933:220:16:-:0;7039:9;7034:112;7058:9;:16;7054:1;:20;7034:112;;;7096:38;7109:5;7116:3;7121:9;7131:1;7121:12;;;;;;;;:::i;:::-;;;;;;;7096;:38::i;:::-;7076:3;;;;:::i;:::-;;;;7034:112;;18174:282:4;18239:4;18329:13;;18319:7;:23;18276:153;;;;-1:-1:-1;;18380:26:4;;;;:17;:26;;;;;;2182:8;18380:44;:49;;18174:282::o;2331:419:17:-;852:42;2522:45;:49;2518:225;;2593:67;;;;;2644:4;2593:67;;;22015:34:21;21964:42;22085:15;;22065:18;;;22058:43;852:42:17;;2593;;21927:18:21;;2593:67:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2588:144;;2688:28;;;;;1809:42:21;1797:55;;2688:28:17;;;1779:74:21;1752:18;;2688:28:17;1633:226:21;16236:408:4;16325:13;16341:16;16349:7;16341;:16::i;:::-;16325:32;-1:-1:-1;719:10:1;16374:28:4;;;;16370:175;;16422:44;16439:5;719:10:1;9768:402:16;:::i;16422:44:4:-;16417:128;;16494:35;;;;;;;;;;;;;;16417:128;16557:24;;;;:15;:24;;;;;;:35;;;;;;;;;;;;;;16608:28;;16557:24;;16608:28;;;;;;;16314:330;16236:408;;:::o;12046:166::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12157:47:4;12176:27;12195:7;12176:18;:27::i;:::-;-1:-1:-1;;;;;;;;14344:41:4;;;;;2065:3;14430:33;;;14396:68;;-1:-1:-1;;;14396:68:4;2182:8;14494:24;;:29;;-1:-1:-1;;;14475:48:4;;;;2586:3;14563:28;;;;-1:-1:-1;;;14534:58:4;-1:-1:-1;14234:366:4;20442:2825;20584:27;20614;20633:7;20614:18;:27::i;:::-;20584:57;;20699:4;20658:45;;20674:19;20658:45;;;20654:86;;20712:28;;;;;;;;;;;;;;20654:86;20754:27;19550:24;;;:15;:24;;;;;19778:26;;20945:68;19778:26;20987:4;719:10:1;20993:19:4;18879:16;19024:32;;;18868:28;;19153:20;;19175:30;;19150:56;;18565:659;20945:68;20940:180;;21033:43;21050:4;719:10:1;9768:402:16;:::i;21033:43:4:-;21028:92;;21085:35;;;;;;;;;;;;;;21028:92;21137:16;;;21133:52;;21162:23;;;;;;;;;;;;;;21133:52;21334:15;21331:160;;;21474:1;21453:19;21446:30;21331:160;21871:24;;;;;;;;:18;:24;;;;;;21869:26;;;;;;21940:22;;;;;;;;;21938:24;;-1:-1:-1;21938:24:4;;;15094:11;15069:23;15065:41;15052:63;2462:8;15052:63;22233:26;;;;:17;:26;;;;;:175;2462:8;22528:47;;22524:627;;22633:1;22623:11;;22601:19;22756:30;;;:17;:30;;;;;;22752:384;;22894:13;;22879:11;:28;22875:242;;23041:30;;;;:17;:30;;;;;:52;;;22875:242;22582:569;22524:627;23198:7;23194:2;23179:27;;23188:4;23179:27;;;;;;;;;;;;20573:2694;;;20442:2825;;;:::o;2644:248:16:-;2745:7;2766:9;2777;2788:7;2799:26;2814:10;2799:14;:26::i;:::-;2843:41;;;;;;;;;;;;22589:25:21;;;22662:4;22650:17;;22630:18;;;22623:45;;;;22684:18;;;22677:34;;;22727:18;;;22720:34;;;2765:60:16;;-1:-1:-1;2765:60:16;;-1:-1:-1;2765:60:16;-1:-1:-1;2843:41:16;;22561:19:21;;2843:41:16;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2843:41:16;;;;;;2644:248;-1:-1:-1;;;;;;;2644:248:16:o;35011:3081:4:-;35091:27;35121;35140:7;35121:18;:27::i;:::-;35091:57;-1:-1:-1;35091:57:4;35161:12;;35283:35;35310:7;19439:27;19550:24;;;:15;:24;;;;;19778:26;;19550:24;;19337:485;35283:35;35226:92;;;;35335:13;35331:316;;;35456:68;35481:15;35498:4;719:10:1;35504:19:4;640:96:1;35456:68:4;35451:184;;35548:43;35565:4;719:10:1;9768:402:16;:::i;35548:43:4:-;35543:92;;35600:35;;;;;;;;;;;;;;35543:92;35803:15;35800:160;;;35943:1;35922:19;35915:30;35800:160;36562:24;;;;;;;:18;:24;;;;;:60;;36590:32;36562:60;;;15094:11;15069:23;15065:41;15052:63;36950:43;15052:63;36860:26;;;;:17;:26;;;;;:205;2462:8;37185:47;;37181:627;;37290:1;37280:11;;37258:19;37413:30;;;:17;:30;;;;;;37409:384;;37551:13;;37536:11;:28;37532:242;;37698:30;;;;:17;:30;;;;;:52;;;37532:242;37239:569;37181:627;37836:35;;37863:7;;37859:1;;37836:35;;;;;;37859:1;;37836:35;-1:-1:-1;;38059:12:4;:14;;;;;;-1:-1:-1;;;;35011:3081:4:o;23363:193::-;23509:39;23526:4;23532:2;23536:7;23509:39;;;;;;;;;;;;:16;:39::i;12860:1275::-;12927:7;12962;13064:13;;13057:4;:20;13053:1015;;;13102:14;13119:23;;;:17;:23;;;;;;2182:8;13208:24;;13204:845;;13873:113;13880:11;13873:113;;-1:-1:-1;13951:6:4;;13933:25;;;;:17;:25;;;;;;13873:113;;13204:845;13079:989;13053:1015;14096:31;;;;;;;;;;;;;;2263:187:18;2355:6;;;;2371:17;;;;;;;;;;;2403:40;;2355:6;;;2371:17;2355:6;;2403:40;;2336:16;;2403:40;2326:124;2263:187;:::o;17361:234:4:-;719:10:1;17456:39:4;;;;:18;:39;;;;;;;;;:49;;;;;;;;;;;;:60;;;;;;;;;;;;;17532:55;;586:41:21;;;17456:49:4;;719:10:1;17532:55:4;;559:18:21;17532:55:4;;;;;;;17361:234;;:::o;24154:407::-;24329:31;24342:4;24348:2;24352:7;24329:12;:31::i;:::-;24375:14;;;;:19;24371:183;;24414:56;24445:4;24451:2;24455:7;24464:5;24414:30;:56::i;:::-;24409:145;;24498:40;;;;;;;;;;;;;;7161:108:16;7221:13;7254:7;7247:14;;;;;:::i;328:703:20:-;384:13;601:10;597:51;;-1:-1:-1;;627:10:20;;;;;;;;;;;;;;;;;;328:703::o;597:51::-;672:5;657:12;711:75;718:9;;711:75;;743:8;;;;:::i;:::-;;-1:-1:-1;765:10:20;;-1:-1:-1;773:2:20;765:10;;:::i;:::-;;;711:75;;;795:19;827:6;817:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;817:17:20;;795:39;;844:150;851:10;;844:150;;877:11;887:1;877:11;;:::i;:::-;;-1:-1:-1;945:10:20;953:2;945:5;:10;:::i;:::-;932:24;;:2;:24;:::i;:::-;919:39;;902:6;909;902:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;972:11:20;981:2;972:11;;:::i;:::-;;;844:150;;27823:2966:4;27896:20;27919:13;27947;27943:44;;27969:18;;;;;;;;;;;;;;27943:44;28475:22;;;;;;;:18;:22;;;;1544:2;28475:22;;;:71;;28513:32;28501:45;;28475:71;;;28789:31;;;:17;:31;;;;;-1:-1:-1;15525:15:4;;15499:24;15495:46;15094:11;15069:23;15065:41;15062:52;15052:63;;28789:173;;29024:23;;;;28789:31;;28475:22;;29789:25;28475:22;;29642:335;30303:1;30289:12;30285:20;30243:346;30344:3;30335:7;30332:16;30243:346;;30562:7;30552:8;30549:1;30522:25;30519:1;30516;30511:59;30397:1;30384:15;30243:346;;;-1:-1:-1;30622:13:4;30618:45;;30644:19;;;;;;;;;;;;;;30618:45;30680:13;:19;-1:-1:-1;1808:165:16;;;:::o;2904:321::-;2968:9;2979;2990:7;3018:3;:10;3032:2;3018:16;3010:53;;;;-1:-1:-1;;;3010:53:16;;23398:2:21;3010:53:16;;;23380:21:21;23437:2;23417:18;;;23410:30;23476:26;23456:18;;;23449:54;23520:18;;3010:53:16;23196:348:21;3010:53:16;-1:-1:-1;;;3118:2:16;3109:12;;3103:19;3156:2;3147:12;;3141:19;3202:2;3193:12;;;3187:19;3103;;3184:1;3179:28;;;;;2904:321::o;26645:716:4:-;26829:88;;;;;26808:4;;26829:45;;;;;;:88;;719:10:1;;26896:4:4;;26902:7;;26911:5;;26829:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26829:88:4;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;26825:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27112:13:4;;27108:235;;27158:40;;;;;;;;;;;;;;27108:235;27301:6;27295:13;27286:6;27282:2;27278:15;27271:38;26825:529;26988:64;;26998:54;26988:64;;-1:-1:-1;26645:716:4;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:177:21;99:66;92:5;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:258::-;710:1;720:113;734:6;731:1;728:13;720:113;;;810:11;;;804:18;791:11;;;784:39;756:2;749:10;720:113;;;851:6;848:1;845:13;842:48;;;-1:-1:-1;;886:1:21;868:16;;861:27;638:258::o;901:317::-;943:3;981:5;975:12;1008:6;1003:3;996:19;1024:63;1080:6;1073:4;1068:3;1064:14;1057:4;1050:5;1046:16;1024:63;:::i;:::-;1132:2;1120:15;1137:66;1116:88;1107:98;;;;1207:4;1103:109;;901:317;-1:-1:-1;;901:317:21:o;1223:220::-;1372:2;1361:9;1354:21;1335:4;1392:45;1433:2;1422:9;1418:18;1410:6;1392:45;:::i;1448:180::-;1507:6;1560:2;1548:9;1539:7;1535:23;1531:32;1528:52;;;1576:1;1573;1566:12;1528:52;-1:-1:-1;1599:23:21;;1448:180;-1:-1:-1;1448:180:21:o;1864:154::-;1950:42;1943:5;1939:54;1932:5;1929:65;1919:93;;2008:1;2005;1998:12;2023:315;2091:6;2099;2152:2;2140:9;2131:7;2127:23;2123:32;2120:52;;;2168:1;2165;2158:12;2120:52;2207:9;2194:23;2226:31;2251:5;2226:31;:::i;:::-;2276:5;2328:2;2313:18;;;;2300:32;;-1:-1:-1;;;2023:315:21:o;3073:456::-;3150:6;3158;3166;3219:2;3207:9;3198:7;3194:23;3190:32;3187:52;;;3235:1;3232;3225:12;3187:52;3274:9;3261:23;3293:31;3318:5;3293:31;:::i;:::-;3343:5;-1:-1:-1;3400:2:21;3385:18;;3372:32;3413:33;3372:32;3413:33;:::i;:::-;3073:456;;3465:7;;-1:-1:-1;;;3519:2:21;3504:18;;;;3491:32;;3073:456::o;3534:118::-;3620:5;3613:13;3606:21;3599:5;3596:32;3586:60;;3642:1;3639;3632:12;3657:241;3713:6;3766:2;3754:9;3745:7;3741:23;3737:32;3734:52;;;3782:1;3779;3772:12;3734:52;3821:9;3808:23;3840:28;3862:5;3840:28;:::i;3903:247::-;3962:6;4015:2;4003:9;3994:7;3990:23;3986:32;3983:52;;;4031:1;4028;4021:12;3983:52;4070:9;4057:23;4089:31;4114:5;4089:31;:::i;4155:184::-;4207:77;4204:1;4197:88;4304:4;4301:1;4294:15;4328:4;4325:1;4318:15;4344:334;4415:2;4409:9;4471:2;4461:13;;4476:66;4457:86;4445:99;;4574:18;4559:34;;4595:22;;;4556:62;4553:88;;;4621:18;;:::i;:::-;4657:2;4650:22;4344:334;;-1:-1:-1;4344:334:21:o;4683:465::-;4747:5;4781:18;4773:6;4770:30;4767:56;;;4803:18;;:::i;:::-;4841:116;4951:4;4882:66;4877:2;4869:6;4865:15;4861:88;4857:99;4841:116;:::i;:::-;4832:125;;4980:6;4973:5;4966:21;5020:3;5011:6;5006:3;5002:16;4999:25;4996:45;;;5037:1;5034;5027:12;4996:45;5086:6;5081:3;5074:4;5067:5;5063:16;5050:43;5140:1;5133:4;5124:6;5117:5;5113:18;5109:29;5102:40;4683:465;;;;;:::o;5153:220::-;5195:5;5248:3;5241:4;5233:6;5229:17;5225:27;5215:55;;5266:1;5263;5256:12;5215:55;5288:79;5363:3;5354:6;5341:20;5334:4;5326:6;5322:17;5288:79;:::i;5378:523::-;5464:6;5472;5480;5533:2;5521:9;5512:7;5508:23;5504:32;5501:52;;;5549:1;5546;5539:12;5501:52;5588:9;5575:23;5607:31;5632:5;5607:31;:::i;:::-;5657:5;-1:-1:-1;5713:2:21;5698:18;;5685:32;5740:18;5729:30;;5726:50;;;5772:1;5769;5762:12;5726:50;5795:49;5836:7;5827:6;5816:9;5812:22;5795:49;:::i;:::-;5785:59;;;5891:2;5880:9;5876:18;5863:32;5853:42;;5378:523;;;;;:::o;5906:367::-;5969:8;5979:6;6033:3;6026:4;6018:6;6014:17;6010:27;6000:55;;6051:1;6048;6041:12;6000:55;-1:-1:-1;6074:20:21;;6117:18;6106:30;;6103:50;;;6149:1;6146;6139:12;6103:50;6186:4;6178:6;6174:17;6162:29;;6246:3;6239:4;6229:6;6226:1;6222:14;6214:6;6210:27;6206:38;6203:47;6200:67;;;6263:1;6260;6253:12;6200:67;5906:367;;;;;:::o;6278:971::-;6418:6;6426;6434;6442;6450;6503:2;6491:9;6482:7;6478:23;6474:32;6471:52;;;6519:1;6516;6509:12;6471:52;6559:9;6546:23;6588:18;6629:2;6621:6;6618:14;6615:34;;;6645:1;6642;6635:12;6615:34;6684:70;6746:7;6737:6;6726:9;6722:22;6684:70;:::i;:::-;6773:8;;-1:-1:-1;6658:96:21;-1:-1:-1;6861:2:21;6846:18;;6833:32;;-1:-1:-1;6877:16:21;;;6874:36;;;6906:1;6903;6896:12;6874:36;6945:72;7009:7;6998:8;6987:9;6983:24;6945:72;:::i;:::-;7036:8;;-1:-1:-1;6919:98:21;-1:-1:-1;7124:2:21;7109:18;;7096:32;;-1:-1:-1;7140:16:21;;;7137:36;;;7169:1;7166;7159:12;7137:36;;7192:51;7235:7;7224:8;7213:9;7209:24;7192:51;:::i;:::-;7182:61;;;6278:971;;;;;;;;:::o;7517:450::-;7586:6;7639:2;7627:9;7618:7;7614:23;7610:32;7607:52;;;7655:1;7652;7645:12;7607:52;7695:9;7682:23;7728:18;7720:6;7717:30;7714:50;;;7760:1;7757;7750:12;7714:50;7783:22;;7836:4;7828:13;;7824:27;-1:-1:-1;7814:55:21;;7865:1;7862;7855:12;7814:55;7888:73;7953:7;7948:2;7935:16;7930:2;7926;7922:11;7888:73;:::i;7972:382::-;8037:6;8045;8098:2;8086:9;8077:7;8073:23;8069:32;8066:52;;;8114:1;8111;8104:12;8066:52;8153:9;8140:23;8172:31;8197:5;8172:31;:::i;:::-;8222:5;-1:-1:-1;8279:2:21;8264:18;;8251:32;8292:30;8251:32;8292:30;:::i;:::-;8341:7;8331:17;;;7972:382;;;;;:::o;8359:665::-;8454:6;8462;8470;8478;8531:3;8519:9;8510:7;8506:23;8502:33;8499:53;;;8548:1;8545;8538:12;8499:53;8587:9;8574:23;8606:31;8631:5;8606:31;:::i;:::-;8656:5;-1:-1:-1;8713:2:21;8698:18;;8685:32;8726:33;8685:32;8726:33;:::i;:::-;8778:7;-1:-1:-1;8832:2:21;8817:18;;8804:32;;-1:-1:-1;8887:2:21;8872:18;;8859:32;8914:18;8903:30;;8900:50;;;8946:1;8943;8936:12;8900:50;8969:49;9010:7;9001:6;8990:9;8986:22;8969:49;:::i;:::-;8959:59;;;8359:665;;;;;;;:::o;9029:456::-;9115:6;9123;9131;9184:2;9172:9;9163:7;9159:23;9155:32;9152:52;;;9200:1;9197;9190:12;9152:52;9236:9;9223:23;9213:33;;9293:2;9282:9;9278:18;9265:32;9255:42;;9348:2;9337:9;9333:18;9320:32;9375:18;9367:6;9364:30;9361:50;;;9407:1;9404;9397:12;9361:50;9430:49;9471:7;9462:6;9451:9;9447:22;9430:49;:::i;:::-;9420:59;;;9029:456;;;;;:::o;9490:1107::-;9639:6;9647;9655;9663;9671;9679;9732:3;9720:9;9711:7;9707:23;9703:33;9700:53;;;9749:1;9746;9739:12;9700:53;9788:9;9775:23;9807:31;9832:5;9807:31;:::i;:::-;9857:5;-1:-1:-1;9913:2:21;9898:18;;9885:32;9936:18;9966:14;;;9963:34;;;9993:1;9990;9983:12;9963:34;10016:49;10057:7;10048:6;10037:9;10033:22;10016:49;:::i;:::-;10006:59;;10118:2;10107:9;10103:18;10090:32;10074:48;;10147:2;10137:8;10134:16;10131:36;;;10163:1;10160;10153:12;10131:36;10202:72;10266:7;10255:8;10244:9;10240:24;10202:72;:::i;:::-;10293:8;;-1:-1:-1;10176:98:21;-1:-1:-1;10381:2:21;10366:18;;10353:32;;-1:-1:-1;10397:16:21;;;10394:36;;;10426:1;10423;10416:12;10394:36;;10465:72;10529:7;10518:8;10507:9;10503:24;10465:72;:::i;:::-;9490:1107;;;;-1:-1:-1;9490:1107:21;;-1:-1:-1;9490:1107:21;;10556:8;;9490:1107;-1:-1:-1;;;9490:1107:21:o;10602:388::-;10670:6;10678;10731:2;10719:9;10710:7;10706:23;10702:32;10699:52;;;10747:1;10744;10737:12;10699:52;10786:9;10773:23;10805:31;10830:5;10805:31;:::i;:::-;10855:5;-1:-1:-1;10912:2:21;10897:18;;10884:32;10925:33;10884:32;10925:33;:::i;10995:773::-;11117:6;11125;11133;11141;11194:2;11182:9;11173:7;11169:23;11165:32;11162:52;;;11210:1;11207;11200:12;11162:52;11250:9;11237:23;11279:18;11320:2;11312:6;11309:14;11306:34;;;11336:1;11333;11326:12;11306:34;11375:70;11437:7;11428:6;11417:9;11413:22;11375:70;:::i;:::-;11464:8;;-1:-1:-1;11349:96:21;-1:-1:-1;11552:2:21;11537:18;;11524:32;;-1:-1:-1;11568:16:21;;;11565:36;;;11597:1;11594;11587:12;11565:36;;11636:72;11700:7;11689:8;11678:9;11674:24;11636:72;:::i;:::-;10995:773;;;;-1:-1:-1;11727:8:21;-1:-1:-1;;;;10995:773:21:o;11773:1222::-;11875:6;11883;11891;11944:2;11932:9;11923:7;11919:23;11915:32;11912:52;;;11960:1;11957;11950:12;11912:52;11999:9;11986:23;12018:31;12043:5;12018:31;:::i;:::-;12068:5;-1:-1:-1;12092:2:21;12131:18;;;12118:32;12159:33;12118:32;12159:33;:::i;:::-;12211:7;-1:-1:-1;12269:2:21;12254:18;;12241:32;12292:18;12322:14;;;12319:34;;;12349:1;12346;12339:12;12319:34;12387:6;12376:9;12372:22;12362:32;;12432:7;12425:4;12421:2;12417:13;12413:27;12403:55;;12454:1;12451;12444:12;12403:55;12490:2;12477:16;12512:2;12508;12505:10;12502:36;;;12518:18;;:::i;:::-;12564:2;12561:1;12557:10;12547:20;;12587:28;12611:2;12607;12603:11;12587:28;:::i;:::-;12649:15;;;12719:11;;;12715:20;;;12680:12;;;;12747:19;;;12744:39;;;12779:1;12776;12769:12;12744:39;12803:11;;;;12823:142;12839:6;12834:3;12831:15;12823:142;;;12905:17;;12893:30;;12856:12;;;;12943;;;;12823:142;;;12984:5;12974:15;;;;;;;;11773:1222;;;;;:::o;13000:437::-;13079:1;13075:12;;;;13122;;;13143:61;;13197:4;13189:6;13185:17;13175:27;;13143:61;13250:2;13242:6;13239:14;13219:18;13216:38;13213:218;;;13287:77;13284:1;13277:88;13388:4;13385:1;13378:15;13416:4;13413:1;13406:15;13213:218;;13000:437;;;:::o;14732:184::-;14784:77;14781:1;14774:88;14881:4;14878:1;14871:15;14905:4;14902:1;14895:15;14921:128;14961:3;14992:1;14988:6;14985:1;14982:13;14979:39;;;14998:18;;:::i;:::-;-1:-1:-1;15034:9:21;;14921:128::o;16532:184::-;16584:77;16581:1;16574:88;16681:4;16678:1;16671:15;16705:4;16702:1;16695:15;17124:195;17163:3;17194:66;17187:5;17184:77;17181:103;;;17264:18;;:::i;:::-;-1:-1:-1;17311:1:21;17300:13;;17124:195::o;18074:470::-;18253:3;18291:6;18285:13;18307:53;18353:6;18348:3;18341:4;18333:6;18329:17;18307:53;:::i;:::-;18423:13;;18382:16;;;;18445:57;18423:13;18382:16;18479:4;18467:17;;18445:57;:::i;:::-;18518:20;;18074:470;-1:-1:-1;;;;18074:470:21:o;18904:125::-;18944:4;18972:1;18969;18966:8;18963:34;;;18977:18;;:::i;:::-;-1:-1:-1;19014:9:21;;18904:125::o;19381:351::-;19451:3;19483:66;19475:6;19472:78;19469:98;;;19563:1;19560;19553:12;19469:98;19599:6;19596:1;19592:14;19640:8;19633:5;19628:3;19615:34;19706:1;19668:18;;19695:13;;;-1:-1:-1;19668:18:21;;19381:351;-1:-1:-1;;19381:351:21:o;19737:579::-;20024:3;20055:58;20109:3;20101:6;20093;20055:58;:::i;:::-;20157:66;20148:6;20144:2;20140:15;20136:88;20129:5;20122:103;20241:69;20306:2;20299:5;20295:14;20287:6;20279;20241:69;:::i;:::-;20234:76;19737:579;-1:-1:-1;;;;;;;;19737:579:21:o;20321:280::-;20420:6;20473:2;20461:9;20452:7;20448:23;20444:32;20441:52;;;20489:1;20486;20479:12;20441:52;20521:9;20515:16;20540:31;20565:5;20540:31;:::i;22112:245::-;22179:6;22232:2;22220:9;22211:7;22207:23;22203:32;22200:52;;;22248:1;22245;22238:12;22200:52;22280:9;22274:16;22299:28;22321:5;22299:28;:::i;22765:184::-;22817:77;22814:1;22807:88;22914:4;22911:1;22904:15;22938:4;22935:1;22928:15;22954:120;22994:1;23020;23010:35;;23025:18;;:::i;:::-;-1:-1:-1;23059:9:21;;22954:120::o;23079:112::-;23111:1;23137;23127:35;;23142:18;;:::i;:::-;-1:-1:-1;23176:9:21;;23079:112::o;23549:512::-;23743:4;23772:42;23853:2;23845:6;23841:15;23830:9;23823:34;23905:2;23897:6;23893:15;23888:2;23877:9;23873:18;23866:43;;23945:6;23940:2;23929:9;23925:18;23918:34;23988:3;23983:2;23972:9;23968:18;23961:31;24009:46;24050:3;24039:9;24035:19;24027:6;24009:46;:::i;:::-;24001:54;23549:512;-1:-1:-1;;;;;;23549:512:21:o;24066:249::-;24135:6;24188:2;24176:9;24167:7;24163:23;24159:32;24156:52;;;24204:1;24201;24194:12;24156:52;24236:9;24230:16;24255:30;24279:5;24255:30;:::i
Swarm Source
ipfs://d41385961fb5df226d9a25f31d9e1621938c51c5053299c875de1ed2f9467647
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.