ETH Price: $3,594.13 (+8.87%)

Token

Aol (AOL)
 

Overview

Max Total Supply

0 AOL

Holders

313

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
15 AOL
0xfe42A5266CE7A21d2d0dAFFC2A1Ab1677b1009Fb
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
AOLNFT

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-05-27
*/

// File: contracts/IgmRenderer.sol

//  ▄▄▄       ▒█████   ▄████▄  
// ▒████▄    ▒██▒  ██▒▒██▀ ▀█  
// ▒██  ▀█▄  ▒██░  ██▒▒▓█    ▄ 
// ░██▄▄▄▄██ ▒██   ██░▒▓▓▄ ▄██▒
//  ▓█   ▓██▒░ ████▓▒░▒ ▓███▀ ░
//  ▒▒   ▓▒█░░ ▒░▒░▒░ ░ ░▒ ▒  ░
//   ▒   ▒▒ ░  ░ ▒ ▒░   ░  ▒   
//   ░   ▒   ░ ░ ░ ▒  ░        
//       ░  ░    ░ ░  ░ ░      
//                    ░       
// https://aolcoin.xyz/
// https://twitter.com/aolcoin
// https://t.co/MwNyKcButP

pragma solidity 0.8.17;

interface IgmRenderer {
    function applyStyle(uint16 id) external;

    function addAddress(uint16 tokenId, address newAddress) external;

    function tokenUri(uint16 id) external view returns (string memory);
}
// File: hardhat/console.sol


pragma solidity >= 0.4.22 <0.9.0;

library console {
	address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);

	function _sendLogPayload(bytes memory payload) private view {
		uint256 payloadLength = payload.length;
		address consoleAddress = CONSOLE_ADDRESS;
		assembly {
			let payloadStart := add(payload, 32)
			let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
		}
	}

	function log() internal view {
		_sendLogPayload(abi.encodeWithSignature("log()"));
	}

	function logInt(int256 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
	}

	function logUint(uint256 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
	}

	function logString(string memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
	}

	function logBool(bool p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
	}

	function logAddress(address p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
	}

	function logBytes(bytes memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
	}

	function logBytes1(bytes1 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
	}

	function logBytes2(bytes2 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
	}

	function logBytes3(bytes3 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
	}

	function logBytes4(bytes4 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
	}

	function logBytes5(bytes5 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
	}

	function logBytes6(bytes6 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
	}

	function logBytes7(bytes7 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
	}

	function logBytes8(bytes8 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
	}

	function logBytes9(bytes9 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
	}

	function logBytes10(bytes10 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
	}

	function logBytes11(bytes11 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
	}

	function logBytes12(bytes12 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
	}

	function logBytes13(bytes13 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
	}

	function logBytes14(bytes14 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
	}

	function logBytes15(bytes15 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
	}

	function logBytes16(bytes16 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
	}

	function logBytes17(bytes17 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
	}

	function logBytes18(bytes18 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
	}

	function logBytes19(bytes19 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
	}

	function logBytes20(bytes20 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
	}

	function logBytes21(bytes21 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
	}

	function logBytes22(bytes22 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
	}

	function logBytes23(bytes23 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
	}

	function logBytes24(bytes24 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
	}

	function logBytes25(bytes25 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
	}

	function logBytes26(bytes26 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
	}

	function logBytes27(bytes27 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
	}

	function logBytes28(bytes28 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
	}

	function logBytes29(bytes29 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
	}

	function logBytes30(bytes30 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
	}

	function logBytes31(bytes31 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
	}

	function logBytes32(bytes32 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
	}

	function log(uint256 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
	}

	function log(string memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
	}

	function log(bool p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
	}

	function log(address p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
	}

	function log(uint256 p0, uint256 p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
	}

	function log(uint256 p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
	}

	function log(uint256 p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
	}

	function log(uint256 p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
	}

	function log(string memory p0, uint256 p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
	}

	function log(string memory p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
	}

	function log(string memory p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
	}

	function log(string memory p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
	}

	function log(bool p0, uint256 p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
	}

	function log(bool p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
	}

	function log(bool p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
	}

	function log(bool p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
	}

	function log(address p0, uint256 p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
	}

	function log(address p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
	}

	function log(address p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
	}

	function log(address p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
	}

	function log(uint256 p0, uint256 p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
	}

	function log(uint256 p0, uint256 p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
	}

	function log(uint256 p0, uint256 p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
	}

	function log(uint256 p0, uint256 p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
	}

	function log(uint256 p0, string memory p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
	}

	function log(uint256 p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
	}

	function log(uint256 p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
	}

	function log(uint256 p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
	}

	function log(uint256 p0, bool p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
	}

	function log(uint256 p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
	}

	function log(uint256 p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
	}

	function log(uint256 p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
	}

	function log(uint256 p0, address p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
	}

	function log(uint256 p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
	}

	function log(uint256 p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
	}

	function log(uint256 p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
	}

	function log(string memory p0, uint256 p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
	}

	function log(string memory p0, uint256 p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
	}

	function log(string memory p0, uint256 p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
	}

	function log(string memory p0, uint256 p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
	}

	function log(string memory p0, address p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
	}

	function log(string memory p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
	}

	function log(string memory p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
	}

	function log(string memory p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
	}

	function log(bool p0, uint256 p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
	}

	function log(bool p0, uint256 p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
	}

	function log(bool p0, uint256 p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
	}

	function log(bool p0, uint256 p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
	}

	function log(bool p0, bool p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
	}

	function log(bool p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
	}

	function log(bool p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
	}

	function log(bool p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
	}

	function log(bool p0, address p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
	}

	function log(bool p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
	}

	function log(bool p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
	}

	function log(bool p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
	}

	function log(address p0, uint256 p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
	}

	function log(address p0, uint256 p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
	}

	function log(address p0, uint256 p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
	}

	function log(address p0, uint256 p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
	}

	function log(address p0, string memory p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
	}

	function log(address p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
	}

	function log(address p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
	}

	function log(address p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
	}

	function log(address p0, bool p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
	}

	function log(address p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
	}

	function log(address p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
	}

	function log(address p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
	}

	function log(address p0, address p1, uint256 p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
	}

	function log(address p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
	}

	function log(address p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
	}

	function log(address p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
	}

	function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, uint256 p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
	}

	function log(uint256 p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint256 p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint256 p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint256 p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint256 p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint256 p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint256 p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint256 p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, uint256 p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
	}

}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

// File: operator-filter-registry/src/lib/Constants.sol


pragma solidity ^0.8.13;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

// File: operator-filter-registry/src/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}

// File: operator-filter-registry/src/OperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @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.
 *         Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract OperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS);

    /// @dev The constructor that is called when the contract is being deployed.
    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));
                }
            }
        }
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    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);
        }
        _;
    }

    /**
     * @dev A helper function to check if an operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    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) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

// File: operator-filter-registry/src/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 * @dev    Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract DefaultOperatorFilterer is OperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {}
}

// File: @openzeppelin/contracts/utils/math/SafeMath.sol


// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: @openzeppelin/contracts/utils/Counters.sol


// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;


/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://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 functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @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;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @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);
}

// File: @openzeppelin/contracts/interfaces/IERC2981.sol


// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner or approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _ownerOf(tokenId) != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId, 1);

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId, 1);

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256, /* firstTokenId */
        uint256 batchSize
    ) internal virtual {
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: contracts/sayaol.sol


pragma solidity 0.8.17;










contract AOLNFT is ERC721("Aol", "AOL"), IERC2981, Ownable, DefaultOperatorFilterer {

    using Counters for Counters.Counter;

    // The number of AOL tokens needed to claim a mint
    uint256 public constant TOKENS_TO_MINT = 69000000000 * 10**18;
    
    // The AOL token contract
    IERC20 public aolToken;

    /* Constants */
    uint256 public MAX_SUPPLY = 3333; 
    uint256 public constant ROYALTY_PERCENTAGE = 5;
    uint256 public constant WALLET_LIMIT = 15;
    uint256 public constant PRICE = 30000000000000000;
    
    /* Variables */
    Counters.Counter private _tokenIdCounter;
    bool public isSaleActive = false;
    bool public isClaimActive = false;
    mapping(address => uint8) public hasMintedCount;
    mapping(address => uint8) public hasClaimedCount;
    IgmRenderer public renderer;

    /* Errors */
    error LimitReachedForWallet();
    error IncorrectAmountForMint();
    error MaxSupplyReached();
    error NotEnoughAllowance(uint256 available, uint256 required);
    error SaleNotActive();
    error SendToAddressZero();
    error TokenDoesNotExist(uint256 id);
    error WithdrawSendFailed();

    constructor() {
    }

    function mint(uint8 quantity) payable public {
        if (!isSaleActive) {
            revert SaleNotActive();
        }

        if (_tokenIdCounter.current()+quantity > MAX_SUPPLY) {
            revert MaxSupplyReached();
        }

        if (hasMintedCount[msg.sender] == WALLET_LIMIT || hasMintedCount[msg.sender]+quantity > WALLET_LIMIT) {
            revert LimitReachedForWallet();
        }

        if (msg.value < PRICE*quantity) {
            revert IncorrectAmountForMint();
        }

        hasMintedCount[msg.sender] += quantity;

        // set params in renderer
        for (uint8 i = 0; i < quantity; i++) {
            uint256 tokenId = _tokenIdCounter.current();
            _tokenIdCounter.increment();
            renderer.applyStyle(uint16(tokenId));
            renderer.addAddress(uint16(tokenId), msg.sender);
            _safeMint(msg.sender, tokenId);
        }

    }

    function claim(uint8 quantity) public {

        require(isClaimActive, "Sale is not currently active");

        uint256 balance = aolToken.balanceOf(msg.sender);
        uint256 eligibleQuantity = balance / TOKENS_TO_MINT; // Calculate how many NFTs they're eligible to mint

        // Ensure the caller has enough AOL tokens to claim the requested number of NFTs
        require(hasClaimedCount[msg.sender] + quantity <= eligibleQuantity, "You do not have enough AOL tokens to claim this amount of NFTs.");

        // Ensure we haven't reached the max supply
        require(_tokenIdCounter.current() + quantity <= MAX_SUPPLY, "Max supply reached");

        // Ensure the wallet limit isn't reached
        require(hasMintedCount[msg.sender] + quantity <= WALLET_LIMIT, "Wallet limit reached");

        hasMintedCount[msg.sender] += quantity;
        hasClaimedCount[msg.sender] += quantity;

        // Mint the NFTs
        for (uint8 i = 0; i < quantity; i++) {
            uint256 tokenId = _tokenIdCounter.current();
            _tokenIdCounter.increment();
            renderer.applyStyle(uint16(tokenId));
            renderer.addAddress(uint16(tokenId), msg.sender);
            _safeMint(msg.sender, tokenId);
        }
    }

    function currentCounterId() external view returns (uint256) {
        return _tokenIdCounter.current();
    }

    function toggleSaleActive(bool _isSaleActive) public onlyOwner {
        isSaleActive = _isSaleActive;
    }

    function setMAX_SUPPLY(uint256 newMaxSupply) public onlyOwner {
        MAX_SUPPLY = newMaxSupply;
    }

    function toggleClaimActive(bool _isClaimActive) public onlyOwner {
        isClaimActive = _isClaimActive;
    }

    function setAOLToken(IERC20 _aoladdres) public onlyOwner {
        aolToken = _aoladdres;
    }

    function setRenderer(address rendererAddress) public onlyOwner {
        renderer = IgmRenderer(rendererAddress);
    }

    function tokenURI(uint256 id) public view override returns (string memory) {
        if (id > MAX_SUPPLY || _tokenIdCounter.current() < id) {
            revert TokenDoesNotExist(id);
        }
        
        return renderer.tokenUri(uint16(id));
    }

    /* ERC 2891 */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        if (!_exists(tokenId)) {
            revert TokenDoesNotExist(tokenId);
        }

        return (address(0x70A49DaA289eD9fAd113be61Af7505A4342edEB2), SafeMath.div(SafeMath.mul(salePrice, ROYALTY_PERCENTAGE), 100));
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    /* Operator Filter */
    function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) {
        super.approve(operator, tokenId);
    }

    function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        renderer.addAddress(uint16(tokenId), to);
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        renderer.addAddress(uint16(tokenId), to);
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public
        override
        onlyAllowedOperator(from)
    {
        renderer.addAddress(uint16(tokenId), to);
        super.safeTransferFrom(from, to, tokenId, data);
    }

    function withdraw(address to) public onlyOwner {
        if (to == address(0)) {
            revert SendToAddressZero();
        }

        uint256 amount = address(this).balance;

        (bool sent,) = payable(to).call{value: amount}("");
        if (!sent) {
            revert WithdrawSendFailed();
        }
        
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"IncorrectAmountForMint","type":"error"},{"inputs":[],"name":"LimitReachedForWallet","type":"error"},{"inputs":[],"name":"MaxSupplyReached","type":"error"},{"inputs":[{"internalType":"uint256","name":"available","type":"uint256"},{"internalType":"uint256","name":"required","type":"uint256"}],"name":"NotEnoughAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"SaleNotActive","type":"error"},{"inputs":[],"name":"SendToAddressZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"WithdrawSendFailed","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":"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":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROYALTY_PERCENTAGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKENS_TO_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WALLET_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aolToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"quantity","type":"uint8"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentCounterId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasClaimedCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasMintedCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"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":"isClaimActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"quantity","type":"uint8"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renderer","outputs":[{"internalType":"contract IgmRenderer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_aoladdres","type":"address"}],"name":"setAOLToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxSupply","type":"uint256"}],"name":"setMAX_SUPPLY","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rendererAddress","type":"address"}],"name":"setRenderer","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":"bool","name":"_isClaimActive","type":"bool"}],"name":"toggleClaimActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isSaleActive","type":"bool"}],"name":"toggleSaleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenURI","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":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052610d056008556000600a60006101000a81548160ff0219169083151502179055506000600a60016101000a81548160ff0219169083151502179055503480156200004d57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600381526020017f416f6c00000000000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f414f4c00000000000000000000000000000000000000000000000000000000008152508160009081620000e291906200065c565b508060019081620000f491906200065c565b505050620001176200010b6200031460201b60201c565b6200031c60201b60201c565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200030c578015620001d2576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200019892919062000788565b600060405180830381600087803b158015620001b357600080fd5b505af1158015620001c8573d6000803e3d6000fd5b505050506200030b565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200028c576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200025292919062000788565b600060405180830381600087803b1580156200026d57600080fd5b505af115801562000282573d6000803e3d6000fd5b505050506200030a565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620002d59190620007b5565b600060405180830381600087803b158015620002f057600080fd5b505af115801562000305573d6000803e3d6000fd5b505050505b5b5b5050620007d2565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200046457607f821691505b6020821081036200047a57620004796200041c565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004e47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620004a5565b620004f08683620004a5565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200053d62000537620005318462000508565b62000512565b62000508565b9050919050565b6000819050919050565b62000559836200051c565b62000571620005688262000544565b848454620004b2565b825550505050565b600090565b6200058862000579565b620005958184846200054e565b505050565b5b81811015620005bd57620005b16000826200057e565b6001810190506200059b565b5050565b601f8211156200060c57620005d68162000480565b620005e18462000495565b81016020851015620005f1578190505b62000609620006008562000495565b8301826200059a565b50505b505050565b600082821c905092915050565b6000620006316000198460080262000611565b1980831691505092915050565b60006200064c83836200061e565b9150826002028217905092915050565b6200066782620003e2565b67ffffffffffffffff811115620006835762000682620003ed565b5b6200068f82546200044b565b6200069c828285620005c1565b600060209050601f831160018114620006d45760008415620006bf578287015190505b620006cb85826200063e565b8655506200073b565b601f198416620006e48662000480565b60005b828110156200070e57848901518255600182019150602085019450602081019050620006e7565b868310156200072e57848901516200072a601f8916826200061e565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620007708262000743565b9050919050565b620007828162000763565b82525050565b60006040820190506200079f600083018562000777565b620007ae602083018462000777565b9392505050565b6000602082019050620007cc600083018462000777565b92915050565b6145b280620007e26000396000f3fe6080604052600436106102255760003560e01c80636352211e116101235780638da5cb5b116100ab578063c87b56dd1161006f578063c87b56dd146107fb578063e66bb34514610838578063e985e9c514610863578063ec9496ba146108a0578063f2fde38b146108c957610225565b80638da5cb5b1461072a57806395d4063f1461075557806395d89b411461077e578063a22cb465146107a9578063b88d4fde146107d257610225565b8063729b000c116100f2578063729b000c146106555780637fc27803146106805780638395dba5146106ab5780638ada6b0f146106d45780638d859f3e146106ff57610225565b80636352211e146105a85780636ecd2306146105e557806370a0823114610601578063715018a61461063e57610225565b806331e896b1116101b157806342842e0e1161017557806342842e0e146104d7578063463b08db1461050057806351cff8d91461052b578063564566a81461055457806356d3163d1461057f57610225565b806331e896b1146103ee57806332cb6b0c14610419578063351ed951146104445780633f8389c01461046f57806341f43434146104ac57610225565b8063081812fc116101f8578063081812fc146102f8578063095ea7b3146103355780631c6e3a6c1461035e57806323b872dd146103875780632a55205a146103b057610225565b806301ffc9a71461022a578063031552021461026757806306fdde03146102a457806307b43b80146102cf575b600080fd5b34801561023657600080fd5b50610251600480360381019061024c9190613011565b6108f2565b60405161025e9190613059565b60405180910390f35b34801561027357600080fd5b5061028e600480360381019061028991906130d2565b61096c565b60405161029b919061311b565b60405180910390f35b3480156102b057600080fd5b506102b961098c565b6040516102c691906131c6565b60405180910390f35b3480156102db57600080fd5b506102f660048036038101906102f19190613214565b610a1e565b005b34801561030457600080fd5b5061031f600480360381019061031a9190613277565b610a43565b60405161032c91906132b3565b60405180910390f35b34801561034157600080fd5b5061035c600480360381019061035791906132ce565b610a89565b005b34801561036a57600080fd5b506103856004803603810190610380919061334c565b610aa2565b005b34801561039357600080fd5b506103ae60048036038101906103a99190613379565b610aee565b005b3480156103bc57600080fd5b506103d760048036038101906103d291906133cc565b610bcc565b6040516103e592919061341b565b60405180910390f35b3480156103fa57600080fd5b50610403610c4e565b60405161041091906134a3565b60405180910390f35b34801561042557600080fd5b5061042e610c74565b60405161043b91906134be565b60405180910390f35b34801561045057600080fd5b50610459610c7a565b60405161046691906134be565b60405180910390f35b34801561047b57600080fd5b50610496600480360381019061049191906130d2565b610c7f565b6040516104a3919061311b565b60405180910390f35b3480156104b857600080fd5b506104c1610c9f565b6040516104ce91906134fa565b60405180910390f35b3480156104e357600080fd5b506104fe60048036038101906104f99190613379565b610cb1565b005b34801561050c57600080fd5b50610515610d8f565b60405161052291906134be565b60405180910390f35b34801561053757600080fd5b50610552600480360381019061054d91906130d2565b610d94565b005b34801561056057600080fd5b50610569610eaf565b6040516105769190613059565b60405180910390f35b34801561058b57600080fd5b506105a660048036038101906105a191906130d2565b610ec2565b005b3480156105b457600080fd5b506105cf60048036038101906105ca9190613277565b610f0e565b6040516105dc91906132b3565b60405180910390f35b6105ff60048036038101906105fa9190613541565b610f94565b005b34801561060d57600080fd5b50610628600480360381019061062391906130d2565b611345565b60405161063591906134be565b60405180910390f35b34801561064a57600080fd5b506106536113fc565b005b34801561066157600080fd5b5061066a611410565b60405161067791906134be565b60405180910390f35b34801561068c57600080fd5b50610695611420565b6040516106a29190613059565b60405180910390f35b3480156106b757600080fd5b506106d260048036038101906106cd9190613214565b611433565b005b3480156106e057600080fd5b506106e9611458565b6040516106f6919061358f565b60405180910390f35b34801561070b57600080fd5b5061071461147e565b60405161072191906134be565b60405180910390f35b34801561073657600080fd5b5061073f611489565b60405161074c91906132b3565b60405180910390f35b34801561076157600080fd5b5061077c60048036038101906107779190613541565b6114b3565b005b34801561078a57600080fd5b506107936119a4565b6040516107a091906131c6565b60405180910390f35b3480156107b557600080fd5b506107d060048036038101906107cb91906135aa565b611a36565b005b3480156107de57600080fd5b506107f960048036038101906107f4919061371f565b611a4f565b005b34801561080757600080fd5b50610822600480360381019061081d9190613277565b611b2f565b60405161082f91906131c6565b60405180910390f35b34801561084457600080fd5b5061084d611c33565b60405161085a91906134be565b60405180910390f35b34801561086f57600080fd5b5061088a600480360381019061088591906137a2565b611c44565b6040516108979190613059565b60405180910390f35b3480156108ac57600080fd5b506108c760048036038101906108c29190613277565b611cd8565b005b3480156108d557600080fd5b506108f060048036038101906108eb91906130d2565b611cea565b005b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610965575061096482611d6d565b5b9050919050565b600b6020528060005260406000206000915054906101000a900460ff1681565b60606000805461099b90613811565b80601f01602080910402602001604051908101604052809291908181526020018280546109c790613811565b8015610a145780601f106109e957610100808354040283529160200191610a14565b820191906000526020600020905b8154815290600101906020018083116109f757829003601f168201915b5050505050905090565b610a26611e4f565b80600a60006101000a81548160ff02191690831515021790555050565b6000610a4e82611ecd565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610a9381611f18565b610a9d8383612015565b505050565b610aaa611e4f565b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b2c57610b2b33611f18565b5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473683856040518363ffffffff1660e01b8152600401610b8992919061385f565b600060405180830381600087803b158015610ba357600080fd5b505af1158015610bb7573d6000803e3d6000fd5b50505050610bc684848461212c565b50505050565b600080610bd88461218c565b610c1957836040517fc927e5bf000000000000000000000000000000000000000000000000000000008152600401610c1091906134be565b60405180910390fd5b7370a49daa289ed9fad113be61af7505a4342edeb2610c43610c3c8560056121cd565b60646121e3565b915091509250929050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60085481565b600f81565b600c6020528060005260406000206000915054906101000a900460ff1681565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cef57610cee33611f18565b5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473683856040518363ffffffff1660e01b8152600401610d4c92919061385f565b600060405180830381600087803b158015610d6657600080fd5b505af1158015610d7a573d6000803e3d6000fd5b50505050610d898484846121f9565b50505050565b600581565b610d9c611e4f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e02576040517f4056dd2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600047905060008273ffffffffffffffffffffffffffffffffffffffff1682604051610e2d906138b9565b60006040518083038185875af1925050503d8060008114610e6a576040519150601f19603f3d011682016040523d82523d6000602084013e610e6f565b606091505b5050905080610eaa576040517fae7636f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b600a60009054906101000a900460ff1681565b610eca611e4f565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080610f1a83612219565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610f8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f829061391a565b60405180910390fd5b80915050919050565b600a60009054906101000a900460ff16610fda576040517fb7b2409700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008548160ff16610feb6009612256565b610ff59190613969565b111561102d576040517fd05cb60900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1614806110e55750600f81600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166110e0919061399d565b60ff16115b1561111c576040517faaa7193300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060ff16666a94d74f43000061113291906139d2565b34101561116b576040517f08f1743e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900460ff166111c6919061399d565b92506101000a81548160ff021916908360ff16021790555060005b8160ff168160ff1610156113415760006111fb6009612256565b90506112076009612264565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e990b443826040518263ffffffff1660e01b81526004016112629190613a14565b600060405180830381600087803b15801561127c57600080fd5b505af1158015611290573d6000803e3d6000fd5b50505050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473682336040518363ffffffff1660e01b81526004016112f192919061385f565b600060405180830381600087803b15801561130b57600080fd5b505af115801561131f573d6000803e3d6000fd5b5050505061132d338261227a565b50808061133990613a2f565b9150506111e1565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90613aca565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611404611e4f565b61140e6000612298565b565b6bdef376571332906a8800000081565b600a60019054906101000a900460ff1681565b61143b611e4f565b80600a60016101000a81548160ff02191690831515021790555050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b666a94d74f43000081565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a60019054906101000a900460ff16611502576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f990613b36565b60405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b815260040161155f91906132b3565b602060405180830381865afa15801561157c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a09190613b6b565b905060006bdef376571332906a88000000826115bc9190613bc7565b90508083600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611617919061399d565b60ff16111561165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165290613c6a565b60405180910390fd5b6008548360ff1661166c6009612256565b6116769190613969565b11156116b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ae90613cd6565b60405180910390fd5b600f83600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611711919061399d565b60ff161115611755576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174c90613d42565b60405180910390fd5b82600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900460ff166117b0919061399d565b92506101000a81548160ff021916908360ff16021790555082600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900460ff16611823919061399d565b92506101000a81548160ff021916908360ff16021790555060005b8360ff168160ff16101561199e5760006118586009612256565b90506118646009612264565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e990b443826040518263ffffffff1660e01b81526004016118bf9190613a14565b600060405180830381600087803b1580156118d957600080fd5b505af11580156118ed573d6000803e3d6000fd5b50505050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473682336040518363ffffffff1660e01b815260040161194e92919061385f565b600060405180830381600087803b15801561196857600080fd5b505af115801561197c573d6000803e3d6000fd5b5050505061198a338261227a565b50808061199690613a2f565b91505061183e565b50505050565b6060600180546119b390613811565b80601f01602080910402602001604051908101604052809291908181526020018280546119df90613811565b8015611a2c5780601f10611a0157610100808354040283529160200191611a2c565b820191906000526020600020905b815481529060010190602001808311611a0f57829003601f168201915b5050505050905090565b81611a4081611f18565b611a4a838361235e565b505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a8d57611a8c33611f18565b5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473684866040518363ffffffff1660e01b8152600401611aea92919061385f565b600060405180830381600087803b158015611b0457600080fd5b505af1158015611b18573d6000803e3d6000fd5b50505050611b2885858585612374565b5050505050565b6060600854821180611b49575081611b476009612256565b105b15611b8b57816040517fc927e5bf000000000000000000000000000000000000000000000000000000008152600401611b8291906134be565b60405180910390fd5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663419eba34836040518263ffffffff1660e01b8152600401611be69190613a14565b600060405180830381865afa158015611c03573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611c2c9190613e03565b9050919050565b6000611c3f6009612256565b905090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ce0611e4f565b8060088190555050565b611cf2611e4f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5890613ebe565b60405180910390fd5b611d6a81612298565b50565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611e3857507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611e485750611e47826123d6565b5b9050919050565b611e57612440565b73ffffffffffffffffffffffffffffffffffffffff16611e75611489565b73ffffffffffffffffffffffffffffffffffffffff1614611ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec290613f2a565b60405180910390fd5b565b611ed68161218c565b611f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0c9061391a565b60405180910390fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612012576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611f8f929190613f4a565b602060405180830381865afa158015611fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd09190613f88565b61201157806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161200891906132b3565b60405180910390fd5b5b50565b600061202082610f0e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612090576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161208790614027565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166120af612440565b73ffffffffffffffffffffffffffffffffffffffff1614806120de57506120dd816120d8612440565b611c44565b5b61211d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612114906140b9565b60405180910390fd5b6121278383612448565b505050565b61213d612137612440565b82612501565b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121739061414b565b60405180910390fd5b612187838383612596565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff166121ae83612219565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600081836121db91906139d2565b905092915050565b600081836121f19190613bc7565b905092915050565b61221483838360405180602001604052806000815250611a4f565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600081600001549050919050565b6001816000016000828254019250508190555050565b61229482826040518060200160405280600081525061288f565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612370612369612440565b83836128ea565b5050565b61238561237f612440565b83612501565b6123c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123bb9061414b565b60405180910390fd5b6123d084848484612a56565b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166124bb83610f0e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061250d83610f0e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061254f575061254e8185611c44565b5b8061258d57508373ffffffffffffffffffffffffffffffffffffffff1661257584610a43565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166125b682610f0e565b73ffffffffffffffffffffffffffffffffffffffff161461260c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612603906141dd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361267b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126729061426f565b60405180910390fd5b6126888383836001612ab2565b8273ffffffffffffffffffffffffffffffffffffffff166126a882610f0e565b73ffffffffffffffffffffffffffffffffffffffff16146126fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f5906141dd565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461288a8383836001612bd8565b505050565b6128998383612bde565b6128a66000848484612dfb565b6128e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128dc90614301565b60405180910390fd5b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612958576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294f9061436d565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612a499190613059565b60405180910390a3505050565b612a61848484612596565b612a6d84848484612dfb565b612aac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aa390614301565b60405180910390fd5b50505050565b6001811115612bd257600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612b465780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612b3e919061438d565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612bd15780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612bc99190613969565b925050819055505b5b50505050565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c449061440d565b60405180910390fd5b612c568161218c565b15612c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8d90614479565b60405180910390fd5b612ca4600083836001612ab2565b612cad8161218c565b15612ced576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce490614479565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612df7600083836001612bd8565b5050565b6000612e1c8473ffffffffffffffffffffffffffffffffffffffff16612f82565b15612f75578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612e45612440565b8786866040518563ffffffff1660e01b8152600401612e6794939291906144ee565b6020604051808303816000875af1925050508015612ea357506040513d601f19601f82011682018060405250810190612ea0919061454f565b60015b612f25573d8060008114612ed3576040519150601f19603f3d011682016040523d82523d6000602084013e612ed8565b606091505b506000815103612f1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f1490614301565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612f7a565b600190505b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fee81612fb9565b8114612ff957600080fd5b50565b60008135905061300b81612fe5565b92915050565b60006020828403121561302757613026612faf565b5b600061303584828501612ffc565b91505092915050565b60008115159050919050565b6130538161303e565b82525050565b600060208201905061306e600083018461304a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061309f82613074565b9050919050565b6130af81613094565b81146130ba57600080fd5b50565b6000813590506130cc816130a6565b92915050565b6000602082840312156130e8576130e7612faf565b5b60006130f6848285016130bd565b91505092915050565b600060ff82169050919050565b613115816130ff565b82525050565b6000602082019050613130600083018461310c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613170578082015181840152602081019050613155565b60008484015250505050565b6000601f19601f8301169050919050565b600061319882613136565b6131a28185613141565b93506131b2818560208601613152565b6131bb8161317c565b840191505092915050565b600060208201905081810360008301526131e0818461318d565b905092915050565b6131f18161303e565b81146131fc57600080fd5b50565b60008135905061320e816131e8565b92915050565b60006020828403121561322a57613229612faf565b5b6000613238848285016131ff565b91505092915050565b6000819050919050565b61325481613241565b811461325f57600080fd5b50565b6000813590506132718161324b565b92915050565b60006020828403121561328d5761328c612faf565b5b600061329b84828501613262565b91505092915050565b6132ad81613094565b82525050565b60006020820190506132c860008301846132a4565b92915050565b600080604083850312156132e5576132e4612faf565b5b60006132f3858286016130bd565b925050602061330485828601613262565b9150509250929050565b600061331982613094565b9050919050565b6133298161330e565b811461333457600080fd5b50565b60008135905061334681613320565b92915050565b60006020828403121561336257613361612faf565b5b600061337084828501613337565b91505092915050565b60008060006060848603121561339257613391612faf565b5b60006133a0868287016130bd565b93505060206133b1868287016130bd565b92505060406133c286828701613262565b9150509250925092565b600080604083850312156133e3576133e2612faf565b5b60006133f185828601613262565b925050602061340285828601613262565b9150509250929050565b61341581613241565b82525050565b600060408201905061343060008301856132a4565b61343d602083018461340c565b9392505050565b6000819050919050565b600061346961346461345f84613074565b613444565b613074565b9050919050565b600061347b8261344e565b9050919050565b600061348d82613470565b9050919050565b61349d81613482565b82525050565b60006020820190506134b86000830184613494565b92915050565b60006020820190506134d3600083018461340c565b92915050565b60006134e482613470565b9050919050565b6134f4816134d9565b82525050565b600060208201905061350f60008301846134eb565b92915050565b61351e816130ff565b811461352957600080fd5b50565b60008135905061353b81613515565b92915050565b60006020828403121561355757613556612faf565b5b60006135658482850161352c565b91505092915050565b600061357982613470565b9050919050565b6135898161356e565b82525050565b60006020820190506135a46000830184613580565b92915050565b600080604083850312156135c1576135c0612faf565b5b60006135cf858286016130bd565b92505060206135e0858286016131ff565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61362c8261317c565b810181811067ffffffffffffffff8211171561364b5761364a6135f4565b5b80604052505050565b600061365e612fa5565b905061366a8282613623565b919050565b600067ffffffffffffffff82111561368a576136896135f4565b5b6136938261317c565b9050602081019050919050565b82818337600083830152505050565b60006136c26136bd8461366f565b613654565b9050828152602081018484840111156136de576136dd6135ef565b5b6136e98482856136a0565b509392505050565b600082601f830112613706576137056135ea565b5b81356137168482602086016136af565b91505092915050565b6000806000806080858703121561373957613738612faf565b5b6000613747878288016130bd565b9450506020613758878288016130bd565b935050604061376987828801613262565b925050606085013567ffffffffffffffff81111561378a57613789612fb4565b5b613796878288016136f1565b91505092959194509250565b600080604083850312156137b9576137b8612faf565b5b60006137c7858286016130bd565b92505060206137d8858286016130bd565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061382957607f821691505b60208210810361383c5761383b6137e2565b5b50919050565b600061ffff82169050919050565b61385981613842565b82525050565b60006040820190506138746000830185613850565b61388160208301846132a4565b9392505050565b600081905092915050565b50565b60006138a3600083613888565b91506138ae82613893565b600082019050919050565b60006138c482613896565b9150819050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613904601883613141565b915061390f826138ce565b602082019050919050565b60006020820190508181036000830152613933816138f7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061397482613241565b915061397f83613241565b92508282019050808211156139975761399661393a565b5b92915050565b60006139a8826130ff565b91506139b3836130ff565b9250828201905060ff8111156139cc576139cb61393a565b5b92915050565b60006139dd82613241565b91506139e883613241565b92508282026139f681613241565b91508282048414831517613a0d57613a0c61393a565b5b5092915050565b6000602082019050613a296000830184613850565b92915050565b6000613a3a826130ff565b915060ff8203613a4d57613a4c61393a565b5b600182019050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613ab4602983613141565b9150613abf82613a58565b604082019050919050565b60006020820190508181036000830152613ae381613aa7565b9050919050565b7f53616c65206973206e6f742063757272656e746c792061637469766500000000600082015250565b6000613b20601c83613141565b9150613b2b82613aea565b602082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b600081519050613b658161324b565b92915050565b600060208284031215613b8157613b80612faf565b5b6000613b8f84828501613b56565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613bd282613241565b9150613bdd83613241565b925082613bed57613bec613b98565b5b828204905092915050565b7f596f7520646f206e6f74206861766520656e6f75676820414f4c20746f6b656e60008201527f7320746f20636c61696d207468697320616d6f756e74206f66204e4654732e00602082015250565b6000613c54603f83613141565b9150613c5f82613bf8565b604082019050919050565b60006020820190508181036000830152613c8381613c47565b9050919050565b7f4d617820737570706c7920726561636865640000000000000000000000000000600082015250565b6000613cc0601283613141565b9150613ccb82613c8a565b602082019050919050565b60006020820190508181036000830152613cef81613cb3565b9050919050565b7f57616c6c6574206c696d69742072656163686564000000000000000000000000600082015250565b6000613d2c601483613141565b9150613d3782613cf6565b602082019050919050565b60006020820190508181036000830152613d5b81613d1f565b9050919050565b600067ffffffffffffffff821115613d7d57613d7c6135f4565b5b613d868261317c565b9050602081019050919050565b6000613da6613da184613d62565b613654565b905082815260208101848484011115613dc257613dc16135ef565b5b613dcd848285613152565b509392505050565b600082601f830112613dea57613de96135ea565b5b8151613dfa848260208601613d93565b91505092915050565b600060208284031215613e1957613e18612faf565b5b600082015167ffffffffffffffff811115613e3757613e36612fb4565b5b613e4384828501613dd5565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613ea8602683613141565b9150613eb382613e4c565b604082019050919050565b60006020820190508181036000830152613ed781613e9b565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613f14602083613141565b9150613f1f82613ede565b602082019050919050565b60006020820190508181036000830152613f4381613f07565b9050919050565b6000604082019050613f5f60008301856132a4565b613f6c60208301846132a4565b9392505050565b600081519050613f82816131e8565b92915050565b600060208284031215613f9e57613f9d612faf565b5b6000613fac84828501613f73565b91505092915050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000614011602183613141565b915061401c82613fb5565b604082019050919050565b6000602082019050818103600083015261404081614004565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b60006140a3603d83613141565b91506140ae82614047565b604082019050919050565b600060208201905081810360008301526140d281614096565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000614135602d83613141565b9150614140826140d9565b604082019050919050565b6000602082019050818103600083015261416481614128565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006141c7602583613141565b91506141d28261416b565b604082019050919050565b600060208201905081810360008301526141f6816141ba565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614259602483613141565b9150614264826141fd565b604082019050919050565b600060208201905081810360008301526142888161424c565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006142eb603283613141565b91506142f68261428f565b604082019050919050565b6000602082019050818103600083015261431a816142de565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614357601983613141565b915061436282614321565b602082019050919050565b600060208201905081810360008301526143868161434a565b9050919050565b600061439882613241565b91506143a383613241565b92508282039050818111156143bb576143ba61393a565b5b92915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006143f7602083613141565b9150614402826143c1565b602082019050919050565b60006020820190508181036000830152614426816143ea565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614463601c83613141565b915061446e8261442d565b602082019050919050565b6000602082019050818103600083015261449281614456565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006144c082614499565b6144ca81856144a4565b93506144da818560208601613152565b6144e38161317c565b840191505092915050565b600060808201905061450360008301876132a4565b61451060208301866132a4565b61451d604083018561340c565b818103606083015261452f81846144b5565b905095945050505050565b60008151905061454981612fe5565b92915050565b60006020828403121561456557614564612faf565b5b60006145738482850161453a565b9150509291505056fea2646970667358221220e7abc160bf11af6d8e4949a33509fb1ce2bd68f6f074c66258f8f529a6b3ed5364736f6c63430008110033

Deployed Bytecode

0x6080604052600436106102255760003560e01c80636352211e116101235780638da5cb5b116100ab578063c87b56dd1161006f578063c87b56dd146107fb578063e66bb34514610838578063e985e9c514610863578063ec9496ba146108a0578063f2fde38b146108c957610225565b80638da5cb5b1461072a57806395d4063f1461075557806395d89b411461077e578063a22cb465146107a9578063b88d4fde146107d257610225565b8063729b000c116100f2578063729b000c146106555780637fc27803146106805780638395dba5146106ab5780638ada6b0f146106d45780638d859f3e146106ff57610225565b80636352211e146105a85780636ecd2306146105e557806370a0823114610601578063715018a61461063e57610225565b806331e896b1116101b157806342842e0e1161017557806342842e0e146104d7578063463b08db1461050057806351cff8d91461052b578063564566a81461055457806356d3163d1461057f57610225565b806331e896b1146103ee57806332cb6b0c14610419578063351ed951146104445780633f8389c01461046f57806341f43434146104ac57610225565b8063081812fc116101f8578063081812fc146102f8578063095ea7b3146103355780631c6e3a6c1461035e57806323b872dd146103875780632a55205a146103b057610225565b806301ffc9a71461022a578063031552021461026757806306fdde03146102a457806307b43b80146102cf575b600080fd5b34801561023657600080fd5b50610251600480360381019061024c9190613011565b6108f2565b60405161025e9190613059565b60405180910390f35b34801561027357600080fd5b5061028e600480360381019061028991906130d2565b61096c565b60405161029b919061311b565b60405180910390f35b3480156102b057600080fd5b506102b961098c565b6040516102c691906131c6565b60405180910390f35b3480156102db57600080fd5b506102f660048036038101906102f19190613214565b610a1e565b005b34801561030457600080fd5b5061031f600480360381019061031a9190613277565b610a43565b60405161032c91906132b3565b60405180910390f35b34801561034157600080fd5b5061035c600480360381019061035791906132ce565b610a89565b005b34801561036a57600080fd5b506103856004803603810190610380919061334c565b610aa2565b005b34801561039357600080fd5b506103ae60048036038101906103a99190613379565b610aee565b005b3480156103bc57600080fd5b506103d760048036038101906103d291906133cc565b610bcc565b6040516103e592919061341b565b60405180910390f35b3480156103fa57600080fd5b50610403610c4e565b60405161041091906134a3565b60405180910390f35b34801561042557600080fd5b5061042e610c74565b60405161043b91906134be565b60405180910390f35b34801561045057600080fd5b50610459610c7a565b60405161046691906134be565b60405180910390f35b34801561047b57600080fd5b50610496600480360381019061049191906130d2565b610c7f565b6040516104a3919061311b565b60405180910390f35b3480156104b857600080fd5b506104c1610c9f565b6040516104ce91906134fa565b60405180910390f35b3480156104e357600080fd5b506104fe60048036038101906104f99190613379565b610cb1565b005b34801561050c57600080fd5b50610515610d8f565b60405161052291906134be565b60405180910390f35b34801561053757600080fd5b50610552600480360381019061054d91906130d2565b610d94565b005b34801561056057600080fd5b50610569610eaf565b6040516105769190613059565b60405180910390f35b34801561058b57600080fd5b506105a660048036038101906105a191906130d2565b610ec2565b005b3480156105b457600080fd5b506105cf60048036038101906105ca9190613277565b610f0e565b6040516105dc91906132b3565b60405180910390f35b6105ff60048036038101906105fa9190613541565b610f94565b005b34801561060d57600080fd5b50610628600480360381019061062391906130d2565b611345565b60405161063591906134be565b60405180910390f35b34801561064a57600080fd5b506106536113fc565b005b34801561066157600080fd5b5061066a611410565b60405161067791906134be565b60405180910390f35b34801561068c57600080fd5b50610695611420565b6040516106a29190613059565b60405180910390f35b3480156106b757600080fd5b506106d260048036038101906106cd9190613214565b611433565b005b3480156106e057600080fd5b506106e9611458565b6040516106f6919061358f565b60405180910390f35b34801561070b57600080fd5b5061071461147e565b60405161072191906134be565b60405180910390f35b34801561073657600080fd5b5061073f611489565b60405161074c91906132b3565b60405180910390f35b34801561076157600080fd5b5061077c60048036038101906107779190613541565b6114b3565b005b34801561078a57600080fd5b506107936119a4565b6040516107a091906131c6565b60405180910390f35b3480156107b557600080fd5b506107d060048036038101906107cb91906135aa565b611a36565b005b3480156107de57600080fd5b506107f960048036038101906107f4919061371f565b611a4f565b005b34801561080757600080fd5b50610822600480360381019061081d9190613277565b611b2f565b60405161082f91906131c6565b60405180910390f35b34801561084457600080fd5b5061084d611c33565b60405161085a91906134be565b60405180910390f35b34801561086f57600080fd5b5061088a600480360381019061088591906137a2565b611c44565b6040516108979190613059565b60405180910390f35b3480156108ac57600080fd5b506108c760048036038101906108c29190613277565b611cd8565b005b3480156108d557600080fd5b506108f060048036038101906108eb91906130d2565b611cea565b005b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610965575061096482611d6d565b5b9050919050565b600b6020528060005260406000206000915054906101000a900460ff1681565b60606000805461099b90613811565b80601f01602080910402602001604051908101604052809291908181526020018280546109c790613811565b8015610a145780601f106109e957610100808354040283529160200191610a14565b820191906000526020600020905b8154815290600101906020018083116109f757829003601f168201915b5050505050905090565b610a26611e4f565b80600a60006101000a81548160ff02191690831515021790555050565b6000610a4e82611ecd565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610a9381611f18565b610a9d8383612015565b505050565b610aaa611e4f565b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b2c57610b2b33611f18565b5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473683856040518363ffffffff1660e01b8152600401610b8992919061385f565b600060405180830381600087803b158015610ba357600080fd5b505af1158015610bb7573d6000803e3d6000fd5b50505050610bc684848461212c565b50505050565b600080610bd88461218c565b610c1957836040517fc927e5bf000000000000000000000000000000000000000000000000000000008152600401610c1091906134be565b60405180910390fd5b7370a49daa289ed9fad113be61af7505a4342edeb2610c43610c3c8560056121cd565b60646121e3565b915091509250929050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60085481565b600f81565b600c6020528060005260406000206000915054906101000a900460ff1681565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610cef57610cee33611f18565b5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473683856040518363ffffffff1660e01b8152600401610d4c92919061385f565b600060405180830381600087803b158015610d6657600080fd5b505af1158015610d7a573d6000803e3d6000fd5b50505050610d898484846121f9565b50505050565b600581565b610d9c611e4f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e02576040517f4056dd2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600047905060008273ffffffffffffffffffffffffffffffffffffffff1682604051610e2d906138b9565b60006040518083038185875af1925050503d8060008114610e6a576040519150601f19603f3d011682016040523d82523d6000602084013e610e6f565b606091505b5050905080610eaa576040517fae7636f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b600a60009054906101000a900460ff1681565b610eca611e4f565b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080610f1a83612219565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610f8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f829061391a565b60405180910390fd5b80915050919050565b600a60009054906101000a900460ff16610fda576040517fb7b2409700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008548160ff16610feb6009612256565b610ff59190613969565b111561102d576040517fd05cb60900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1614806110e55750600f81600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166110e0919061399d565b60ff16115b1561111c576040517faaa7193300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060ff16666a94d74f43000061113291906139d2565b34101561116b576040517f08f1743e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900460ff166111c6919061399d565b92506101000a81548160ff021916908360ff16021790555060005b8160ff168160ff1610156113415760006111fb6009612256565b90506112076009612264565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e990b443826040518263ffffffff1660e01b81526004016112629190613a14565b600060405180830381600087803b15801561127c57600080fd5b505af1158015611290573d6000803e3d6000fd5b50505050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473682336040518363ffffffff1660e01b81526004016112f192919061385f565b600060405180830381600087803b15801561130b57600080fd5b505af115801561131f573d6000803e3d6000fd5b5050505061132d338261227a565b50808061133990613a2f565b9150506111e1565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90613aca565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611404611e4f565b61140e6000612298565b565b6bdef376571332906a8800000081565b600a60019054906101000a900460ff1681565b61143b611e4f565b80600a60016101000a81548160ff02191690831515021790555050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b666a94d74f43000081565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a60019054906101000a900460ff16611502576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f990613b36565b60405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b815260040161155f91906132b3565b602060405180830381865afa15801561157c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a09190613b6b565b905060006bdef376571332906a88000000826115bc9190613bc7565b90508083600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611617919061399d565b60ff16111561165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165290613c6a565b60405180910390fd5b6008548360ff1661166c6009612256565b6116769190613969565b11156116b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ae90613cd6565b60405180910390fd5b600f83600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611711919061399d565b60ff161115611755576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174c90613d42565b60405180910390fd5b82600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900460ff166117b0919061399d565b92506101000a81548160ff021916908360ff16021790555082600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900460ff16611823919061399d565b92506101000a81548160ff021916908360ff16021790555060005b8360ff168160ff16101561199e5760006118586009612256565b90506118646009612264565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e990b443826040518263ffffffff1660e01b81526004016118bf9190613a14565b600060405180830381600087803b1580156118d957600080fd5b505af11580156118ed573d6000803e3d6000fd5b50505050600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473682336040518363ffffffff1660e01b815260040161194e92919061385f565b600060405180830381600087803b15801561196857600080fd5b505af115801561197c573d6000803e3d6000fd5b5050505061198a338261227a565b50808061199690613a2f565b91505061183e565b50505050565b6060600180546119b390613811565b80601f01602080910402602001604051908101604052809291908181526020018280546119df90613811565b8015611a2c5780601f10611a0157610100808354040283529160200191611a2c565b820191906000526020600020905b815481529060010190602001808311611a0f57829003601f168201915b5050505050905090565b81611a4081611f18565b611a4a838361235e565b505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a8d57611a8c33611f18565b5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631e72473684866040518363ffffffff1660e01b8152600401611aea92919061385f565b600060405180830381600087803b158015611b0457600080fd5b505af1158015611b18573d6000803e3d6000fd5b50505050611b2885858585612374565b5050505050565b6060600854821180611b49575081611b476009612256565b105b15611b8b57816040517fc927e5bf000000000000000000000000000000000000000000000000000000008152600401611b8291906134be565b60405180910390fd5b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663419eba34836040518263ffffffff1660e01b8152600401611be69190613a14565b600060405180830381865afa158015611c03573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611c2c9190613e03565b9050919050565b6000611c3f6009612256565b905090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ce0611e4f565b8060088190555050565b611cf2611e4f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5890613ebe565b60405180910390fd5b611d6a81612298565b50565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611e3857507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611e485750611e47826123d6565b5b9050919050565b611e57612440565b73ffffffffffffffffffffffffffffffffffffffff16611e75611489565b73ffffffffffffffffffffffffffffffffffffffff1614611ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec290613f2a565b60405180910390fd5b565b611ed68161218c565b611f15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0c9061391a565b60405180910390fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612012576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611f8f929190613f4a565b602060405180830381865afa158015611fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd09190613f88565b61201157806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161200891906132b3565b60405180910390fd5b5b50565b600061202082610f0e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612090576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161208790614027565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166120af612440565b73ffffffffffffffffffffffffffffffffffffffff1614806120de57506120dd816120d8612440565b611c44565b5b61211d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612114906140b9565b60405180910390fd5b6121278383612448565b505050565b61213d612137612440565b82612501565b61217c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121739061414b565b60405180910390fd5b612187838383612596565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff166121ae83612219565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600081836121db91906139d2565b905092915050565b600081836121f19190613bc7565b905092915050565b61221483838360405180602001604052806000815250611a4f565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600081600001549050919050565b6001816000016000828254019250508190555050565b61229482826040518060200160405280600081525061288f565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612370612369612440565b83836128ea565b5050565b61238561237f612440565b83612501565b6123c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123bb9061414b565b60405180910390fd5b6123d084848484612a56565b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166124bb83610f0e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061250d83610f0e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061254f575061254e8185611c44565b5b8061258d57508373ffffffffffffffffffffffffffffffffffffffff1661257584610a43565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166125b682610f0e565b73ffffffffffffffffffffffffffffffffffffffff161461260c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612603906141dd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361267b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126729061426f565b60405180910390fd5b6126888383836001612ab2565b8273ffffffffffffffffffffffffffffffffffffffff166126a882610f0e565b73ffffffffffffffffffffffffffffffffffffffff16146126fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f5906141dd565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461288a8383836001612bd8565b505050565b6128998383612bde565b6128a66000848484612dfb565b6128e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128dc90614301565b60405180910390fd5b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612958576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294f9061436d565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612a499190613059565b60405180910390a3505050565b612a61848484612596565b612a6d84848484612dfb565b612aac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aa390614301565b60405180910390fd5b50505050565b6001811115612bd257600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612b465780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612b3e919061438d565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612bd15780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612bc99190613969565b925050819055505b5b50505050565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c449061440d565b60405180910390fd5b612c568161218c565b15612c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8d90614479565b60405180910390fd5b612ca4600083836001612ab2565b612cad8161218c565b15612ced576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ce490614479565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612df7600083836001612bd8565b5050565b6000612e1c8473ffffffffffffffffffffffffffffffffffffffff16612f82565b15612f75578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612e45612440565b8786866040518563ffffffff1660e01b8152600401612e6794939291906144ee565b6020604051808303816000875af1925050508015612ea357506040513d601f19601f82011682018060405250810190612ea0919061454f565b60015b612f25573d8060008114612ed3576040519150601f19603f3d011682016040523d82523d6000602084013e612ed8565b606091505b506000815103612f1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f1490614301565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612f7a565b600190505b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fee81612fb9565b8114612ff957600080fd5b50565b60008135905061300b81612fe5565b92915050565b60006020828403121561302757613026612faf565b5b600061303584828501612ffc565b91505092915050565b60008115159050919050565b6130538161303e565b82525050565b600060208201905061306e600083018461304a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061309f82613074565b9050919050565b6130af81613094565b81146130ba57600080fd5b50565b6000813590506130cc816130a6565b92915050565b6000602082840312156130e8576130e7612faf565b5b60006130f6848285016130bd565b91505092915050565b600060ff82169050919050565b613115816130ff565b82525050565b6000602082019050613130600083018461310c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613170578082015181840152602081019050613155565b60008484015250505050565b6000601f19601f8301169050919050565b600061319882613136565b6131a28185613141565b93506131b2818560208601613152565b6131bb8161317c565b840191505092915050565b600060208201905081810360008301526131e0818461318d565b905092915050565b6131f18161303e565b81146131fc57600080fd5b50565b60008135905061320e816131e8565b92915050565b60006020828403121561322a57613229612faf565b5b6000613238848285016131ff565b91505092915050565b6000819050919050565b61325481613241565b811461325f57600080fd5b50565b6000813590506132718161324b565b92915050565b60006020828403121561328d5761328c612faf565b5b600061329b84828501613262565b91505092915050565b6132ad81613094565b82525050565b60006020820190506132c860008301846132a4565b92915050565b600080604083850312156132e5576132e4612faf565b5b60006132f3858286016130bd565b925050602061330485828601613262565b9150509250929050565b600061331982613094565b9050919050565b6133298161330e565b811461333457600080fd5b50565b60008135905061334681613320565b92915050565b60006020828403121561336257613361612faf565b5b600061337084828501613337565b91505092915050565b60008060006060848603121561339257613391612faf565b5b60006133a0868287016130bd565b93505060206133b1868287016130bd565b92505060406133c286828701613262565b9150509250925092565b600080604083850312156133e3576133e2612faf565b5b60006133f185828601613262565b925050602061340285828601613262565b9150509250929050565b61341581613241565b82525050565b600060408201905061343060008301856132a4565b61343d602083018461340c565b9392505050565b6000819050919050565b600061346961346461345f84613074565b613444565b613074565b9050919050565b600061347b8261344e565b9050919050565b600061348d82613470565b9050919050565b61349d81613482565b82525050565b60006020820190506134b86000830184613494565b92915050565b60006020820190506134d3600083018461340c565b92915050565b60006134e482613470565b9050919050565b6134f4816134d9565b82525050565b600060208201905061350f60008301846134eb565b92915050565b61351e816130ff565b811461352957600080fd5b50565b60008135905061353b81613515565b92915050565b60006020828403121561355757613556612faf565b5b60006135658482850161352c565b91505092915050565b600061357982613470565b9050919050565b6135898161356e565b82525050565b60006020820190506135a46000830184613580565b92915050565b600080604083850312156135c1576135c0612faf565b5b60006135cf858286016130bd565b92505060206135e0858286016131ff565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61362c8261317c565b810181811067ffffffffffffffff8211171561364b5761364a6135f4565b5b80604052505050565b600061365e612fa5565b905061366a8282613623565b919050565b600067ffffffffffffffff82111561368a576136896135f4565b5b6136938261317c565b9050602081019050919050565b82818337600083830152505050565b60006136c26136bd8461366f565b613654565b9050828152602081018484840111156136de576136dd6135ef565b5b6136e98482856136a0565b509392505050565b600082601f830112613706576137056135ea565b5b81356137168482602086016136af565b91505092915050565b6000806000806080858703121561373957613738612faf565b5b6000613747878288016130bd565b9450506020613758878288016130bd565b935050604061376987828801613262565b925050606085013567ffffffffffffffff81111561378a57613789612fb4565b5b613796878288016136f1565b91505092959194509250565b600080604083850312156137b9576137b8612faf565b5b60006137c7858286016130bd565b92505060206137d8858286016130bd565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061382957607f821691505b60208210810361383c5761383b6137e2565b5b50919050565b600061ffff82169050919050565b61385981613842565b82525050565b60006040820190506138746000830185613850565b61388160208301846132a4565b9392505050565b600081905092915050565b50565b60006138a3600083613888565b91506138ae82613893565b600082019050919050565b60006138c482613896565b9150819050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613904601883613141565b915061390f826138ce565b602082019050919050565b60006020820190508181036000830152613933816138f7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061397482613241565b915061397f83613241565b92508282019050808211156139975761399661393a565b5b92915050565b60006139a8826130ff565b91506139b3836130ff565b9250828201905060ff8111156139cc576139cb61393a565b5b92915050565b60006139dd82613241565b91506139e883613241565b92508282026139f681613241565b91508282048414831517613a0d57613a0c61393a565b5b5092915050565b6000602082019050613a296000830184613850565b92915050565b6000613a3a826130ff565b915060ff8203613a4d57613a4c61393a565b5b600182019050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613ab4602983613141565b9150613abf82613a58565b604082019050919050565b60006020820190508181036000830152613ae381613aa7565b9050919050565b7f53616c65206973206e6f742063757272656e746c792061637469766500000000600082015250565b6000613b20601c83613141565b9150613b2b82613aea565b602082019050919050565b60006020820190508181036000830152613b4f81613b13565b9050919050565b600081519050613b658161324b565b92915050565b600060208284031215613b8157613b80612faf565b5b6000613b8f84828501613b56565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613bd282613241565b9150613bdd83613241565b925082613bed57613bec613b98565b5b828204905092915050565b7f596f7520646f206e6f74206861766520656e6f75676820414f4c20746f6b656e60008201527f7320746f20636c61696d207468697320616d6f756e74206f66204e4654732e00602082015250565b6000613c54603f83613141565b9150613c5f82613bf8565b604082019050919050565b60006020820190508181036000830152613c8381613c47565b9050919050565b7f4d617820737570706c7920726561636865640000000000000000000000000000600082015250565b6000613cc0601283613141565b9150613ccb82613c8a565b602082019050919050565b60006020820190508181036000830152613cef81613cb3565b9050919050565b7f57616c6c6574206c696d69742072656163686564000000000000000000000000600082015250565b6000613d2c601483613141565b9150613d3782613cf6565b602082019050919050565b60006020820190508181036000830152613d5b81613d1f565b9050919050565b600067ffffffffffffffff821115613d7d57613d7c6135f4565b5b613d868261317c565b9050602081019050919050565b6000613da6613da184613d62565b613654565b905082815260208101848484011115613dc257613dc16135ef565b5b613dcd848285613152565b509392505050565b600082601f830112613dea57613de96135ea565b5b8151613dfa848260208601613d93565b91505092915050565b600060208284031215613e1957613e18612faf565b5b600082015167ffffffffffffffff811115613e3757613e36612fb4565b5b613e4384828501613dd5565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613ea8602683613141565b9150613eb382613e4c565b604082019050919050565b60006020820190508181036000830152613ed781613e9b565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613f14602083613141565b9150613f1f82613ede565b602082019050919050565b60006020820190508181036000830152613f4381613f07565b9050919050565b6000604082019050613f5f60008301856132a4565b613f6c60208301846132a4565b9392505050565b600081519050613f82816131e8565b92915050565b600060208284031215613f9e57613f9d612faf565b5b6000613fac84828501613f73565b91505092915050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000614011602183613141565b915061401c82613fb5565b604082019050919050565b6000602082019050818103600083015261404081614004565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b60006140a3603d83613141565b91506140ae82614047565b604082019050919050565b600060208201905081810360008301526140d281614096565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000614135602d83613141565b9150614140826140d9565b604082019050919050565b6000602082019050818103600083015261416481614128565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006141c7602583613141565b91506141d28261416b565b604082019050919050565b600060208201905081810360008301526141f6816141ba565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614259602483613141565b9150614264826141fd565b604082019050919050565b600060208201905081810360008301526142888161424c565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006142eb603283613141565b91506142f68261428f565b604082019050919050565b6000602082019050818103600083015261431a816142de565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614357601983613141565b915061436282614321565b602082019050919050565b600060208201905081810360008301526143868161434a565b9050919050565b600061439882613241565b91506143a383613241565b92508282039050818111156143bb576143ba61393a565b5b92915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006143f7602083613141565b9150614402826143c1565b602082019050919050565b60006020820190508181036000830152614426816143ea565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614463601c83613141565b915061446e8261442d565b602082019050919050565b6000602082019050818103600083015261449281614456565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006144c082614499565b6144ca81856144a4565b93506144da818560208601613152565b6144e38161317c565b840191505092915050565b600060808201905061450360008301876132a4565b61451060208301866132a4565b61451d604083018561340c565b818103606083015261452f81846144b5565b905095945050505050565b60008151905061454981612fe5565b92915050565b60006020828403121561456557614564612faf565b5b60006145738482850161453a565b9150509291505056fea2646970667358221220e7abc160bf11af6d8e4949a33509fb1ce2bd68f6f074c66258f8f529a6b3ed5364736f6c63430008110033

Deployed Bytecode Sourcemap

144285:6509:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;149112:215;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144985:47;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126593:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;147819:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;128105:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;149546:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;148173:97;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;149711:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;148695:409;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;144583:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144635:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144728:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;145039:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77064:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;149933:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;144675:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;150450:339;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;144906:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;148278:121;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126303:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;145487:929;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126034:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;143388:103;;;;;;;;;;;;;:::i;:::-;;144478:61;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144945:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;148051:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;145094:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144776:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;142740:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;146424:1268;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126762:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;149362:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;150163:279;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;148407:260;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;147700:111;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;128574:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;147937:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;143646:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;149112:215;149214:4;149253:26;149238:41;;;:11;:41;;;;:81;;;;149283:36;149307:11;149283:23;:36::i;:::-;149238:81;149231:88;;149112:215;;;:::o;144985:47::-;;;;;;;;;;;;;;;;;;;;;;:::o;126593:100::-;126647:13;126680:5;126673:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126593:100;:::o;147819:110::-;142626:13;:11;:13::i;:::-;147908::::1;147893:12;;:28;;;;;;;;;;;;;;;;;;147819:110:::0;:::o;128105:171::-;128181:7;128201:23;128216:7;128201:14;:23::i;:::-;128244:15;:24;128260:7;128244:24;;;;;;;;;;;;;;;;;;;;;128237:31;;128105:171;;;:::o;149546:157::-;149642:8;78846:30;78867:8;78846:20;:30::i;:::-;149663:32:::1;149677:8;149687:7;149663:13;:32::i;:::-;149546:157:::0;;;:::o;148173:97::-;142626:13;:11;:13::i;:::-;148252:10:::1;148241:8;;:21;;;;;;;;;;;;;;;;;;148173:97:::0;:::o;149711:214::-;149812:4;78580:10;78572:18;;:4;:18;;;78568:83;;78607:32;78628:10;78607:20;:32::i;:::-;78568:83;149829:8:::1;;;;;;;;;;;:19;;;149856:7;149866:2;149829:40;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;149880:37;149899:4;149905:2;149909:7;149880:18;:37::i;:::-;149711:214:::0;;;;:::o;148695:409::-;148820:16;148838:21;148882:16;148890:7;148882;:16::i;:::-;148877:83;;148940:7;148922:26;;;;;;;;;;;:::i;:::-;;;;;;;;148877:83;148988:42;149033:62;149046:43;149059:9;144720:1;149046:12;:43::i;:::-;149091:3;149033:12;:62::i;:::-;148972:124;;;;148695:409;;;;;:::o;144583:22::-;;;;;;;;;;;;;:::o;144635:32::-;;;;:::o;144728:41::-;144767:2;144728:41;:::o;145039:48::-;;;;;;;;;;;;;;;;;;;;;;:::o;77064:143::-;69480:42;77064:143;:::o;149933:222::-;150038:4;78580:10;78572:18;;:4;:18;;;78568:83;;78607:32;78628:10;78607:20;:32::i;:::-;78568:83;150055:8:::1;;;;;;;;;;;:19;;;150082:7;150092:2;150055:40;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;150106:41;150129:4;150135:2;150139:7;150106:22;:41::i;:::-;149933:222:::0;;;;:::o;144675:46::-;144720:1;144675:46;:::o;150450:339::-;142626:13;:11;:13::i;:::-;150526:1:::1;150512:16;;:2;:16;;::::0;150508:75:::1;;150552:19;;;;;;;;;;;;;;150508:75;150595:14;150612:21;150595:38;;150647:9;150669:2;150661:16;;150685:6;150661:35;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;150646:50;;;150712:4;150707:65;;150740:20;;;;;;;;;;;;;;150707:65;150497:292;;150450:339:::0;:::o;144906:32::-;;;;;;;;;;;;;:::o;148278:121::-;142626:13;:11;:13::i;:::-;148375:15:::1;148352:8;;:39;;;;;;;;;;;;;;;;;;148278:121:::0;:::o;126303:223::-;126375:7;126395:13;126411:17;126420:7;126411:8;:17::i;:::-;126395:33;;126464:1;126447:19;;:5;:19;;;126439:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;126513:5;126506:12;;;126303:223;;;:::o;145487:929::-;145548:12;;;;;;;;;;;145543:68;;145584:15;;;;;;;;;;;;;;145543:68;145664:10;;145653:8;145627:34;;:25;:15;:23;:25::i;:::-;:34;;;;:::i;:::-;:47;145623:105;;;145698:18;;;;;;;;;;;;;;145623:105;144767:2;145744:14;:26;145759:10;145744:26;;;;;;;;;;;;;;;;;;;;;;;;;:42;;;:96;;;;144767:2;145817:8;145790:14;:26;145805:10;145790:26;;;;;;;;;;;;;;;;;;;;;;;;;:35;;;;:::i;:::-;:50;;;145744:96;145740:159;;;145864:23;;;;;;;;;;;;;;145740:159;145933:8;145927:14;;144808:17;145927:14;;;;:::i;:::-;145915:9;:26;145911:90;;;145965:24;;;;;;;;;;;;;;145911:90;146043:8;146013:14;:26;146028:10;146013:26;;;;;;;;;;;;;;;;:38;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;146104:7;146099:308;146121:8;146117:12;;:1;:12;;;146099:308;;;146151:15;146169:25;:15;:23;:25::i;:::-;146151:43;;146209:27;:15;:25;:27::i;:::-;146251:8;;;;;;;;;;;:19;;;146278:7;146251:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;146302:8;;;;;;;;;;;:19;;;146329:7;146339:10;146302:48;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;146365:30;146375:10;146387:7;146365:9;:30::i;:::-;146136:271;146131:3;;;;;:::i;:::-;;;;146099:308;;;;145487:929;:::o;126034:207::-;126106:7;126151:1;126134:19;;:5;:19;;;126126:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;126217:9;:16;126227:5;126217:16;;;;;;;;;;;;;;;;126210:23;;126034:207;;;:::o;143388:103::-;142626:13;:11;:13::i;:::-;143453:30:::1;143480:1;143453:18;:30::i;:::-;143388:103::o:0;144478:61::-;144519:20;144478:61;:::o;144945:33::-;;;;;;;;;;;;;:::o;148051:114::-;142626:13;:11;:13::i;:::-;148143:14:::1;148127:13;;:30;;;;;;;;;;;;;;;;;;148051:114:::0;:::o;145094:27::-;;;;;;;;;;;;;:::o;144776:49::-;144808:17;144776:49;:::o;142740:87::-;142786:7;142813:6;;;;;;;;;;;142806:13;;142740:87;:::o;146424:1268::-;146483:13;;;;;;;;;;;146475:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;146542:15;146560:8;;;;;;;;;;;:18;;;146579:10;146560:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;146542:48;;146601:24;144519:20;146628:7;:24;;;;:::i;:::-;146601:51;;146857:16;146845:8;146815:15;:27;146831:10;146815:27;;;;;;;;;;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;:58;;;;146807:134;;;;;;;;;;;;:::i;:::-;;;;;;;;;147055:10;;147043:8;147015:36;;:25;:15;:23;:25::i;:::-;:36;;;;:::i;:::-;:50;;147007:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;144767:2;147188:8;147159:14;:26;147174:10;147159:26;;;;;;;;;;;;;;;;;;;;;;;;;:37;;;;:::i;:::-;:53;;;;147151:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;147280:8;147250:14;:26;147265:10;147250:26;;;;;;;;;;;;;;;;:38;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;147330:8;147299:15;:27;147315:10;147299:27;;;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;147382:7;147377:308;147399:8;147395:12;;:1;:12;;;147377:308;;;147429:15;147447:25;:15;:23;:25::i;:::-;147429:43;;147487:27;:15;:25;:27::i;:::-;147529:8;;;;;;;;;;;:19;;;147556:7;147529:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;147580:8;;;;;;;;;;;:19;;;147607:7;147617:10;147580:48;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;147643:30;147653:10;147665:7;147643:9;:30::i;:::-;147414:271;147409:3;;;;;:::i;:::-;;;;147377:308;;;;146462:1230;;146424:1268;:::o;126762:104::-;126818:13;126851:7;126844:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126762:104;:::o;149362:176::-;149466:8;78846:30;78867:8;78846:20;:30::i;:::-;149487:43:::1;149511:8;149521;149487:23;:43::i;:::-;149362:176:::0;;;:::o;150163:279::-;150314:4;78580:10;78572:18;;:4;:18;;;78568:83;;78607:32;78628:10;78607:20;:32::i;:::-;78568:83;150336:8:::1;;;;;;;;;;;:19;;;150363:7;150373:2;150336:40;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;150387:47;150410:4;150416:2;150420:7;150429:4;150387:22;:47::i;:::-;150163:279:::0;;;;;:::o;148407:260::-;148467:13;148502:10;;148497:2;:15;:49;;;;148544:2;148516:25;:15;:23;:25::i;:::-;:30;148497:49;148493:110;;;148588:2;148570:21;;;;;;;;;;;:::i;:::-;;;;;;;;148493:110;148630:8;;;;;;;;;;;:17;;;148655:2;148630:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;148623:36;;148407:260;;;:::o;147700:111::-;147751:7;147778:25;:15;:23;:25::i;:::-;147771:32;;147700:111;:::o;128574:164::-;128671:4;128695:18;:25;128714:5;128695:25;;;;;;;;;;;;;;;:35;128721:8;128695:35;;;;;;;;;;;;;;;;;;;;;;;;;128688:42;;128574:164;;;;:::o;147937:106::-;142626:13;:11;:13::i;:::-;148023:12:::1;148010:10;:25;;;;147937:106:::0;:::o;143646:201::-;142626:13;:11;:13::i;:::-;143755:1:::1;143735:22;;:8;:22;;::::0;143727:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;143811:28;143830:8;143811:18;:28::i;:::-;143646:201:::0;:::o;125665:305::-;125767:4;125819:25;125804:40;;;:11;:40;;;;:105;;;;125876:33;125861:48;;;:11;:48;;;;125804:105;:158;;;;125926:36;125950:11;125926:23;:36::i;:::-;125804:158;125784:178;;125665:305;;;:::o;142905:132::-;142980:12;:10;:12::i;:::-;142969:23;;:7;:5;:7::i;:::-;:23;;;142961:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;142905:132::o;137924:135::-;138006:16;138014:7;138006;:16::i;:::-;137998:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;137924:135;:::o;78989:647::-;79228:1;69480:42;79180:45;;;:49;79176:453;;;69480:42;79479;;;79530:4;79537:8;79479:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79474:144;;79593:8;79574:28;;;;;;;;;;;:::i;:::-;;;;;;;;79474:144;79176:453;78989:647;:::o;127623:416::-;127704:13;127720:23;127735:7;127720:14;:23::i;:::-;127704:39;;127768:5;127762:11;;:2;:11;;;127754:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;127862:5;127846:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;127871:37;127888:5;127895:12;:10;:12::i;:::-;127871:16;:37::i;:::-;127846:62;127824:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;128010:21;128019:2;128023:7;128010:8;:21::i;:::-;127693:346;127623:416;;:::o;128805:335::-;129000:41;129019:12;:10;:12::i;:::-;129033:7;129000:18;:41::i;:::-;128992:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;129104:28;129114:4;129120:2;129124:7;129104:9;:28::i;:::-;128805:335;;;:::o;131527:128::-;131592:4;131645:1;131616:31;;:17;131625:7;131616:8;:17::i;:::-;:31;;;;131609:38;;131527:128;;;:::o;84031:98::-;84089:7;84120:1;84116;:5;;;;:::i;:::-;84109:12;;84031:98;;;;:::o;84430:::-;84488:7;84519:1;84515;:5;;;;:::i;:::-;84508:12;;84430:98;;;;:::o;129211:185::-;129349:39;129366:4;129372:2;129376:7;129349:39;;;;;;;;;;;;:16;:39::i;:::-;129211:185;;;:::o;131097:117::-;131163:7;131190;:16;131198:7;131190:16;;;;;;;;;;;;;;;;;;;;;131183:23;;131097:117;;;:::o;88330:114::-;88395:7;88422;:14;;;88415:21;;88330:114;;;:::o;88452:127::-;88559:1;88541:7;:14;;;:19;;;;;;;;;;;88452:127;:::o;132428:110::-;132504:26;132514:2;132518:7;132504:26;;;;;;;;;;;;:9;:26::i;:::-;132428:110;;:::o;144007:191::-;144081:16;144100:6;;;;;;;;;;;144081:25;;144126:8;144117:6;;:17;;;;;;;;;;;;;;;;;;144181:8;144150:40;;144171:8;144150:40;;;;;;;;;;;;144070:128;144007:191;:::o;128348:155::-;128443:52;128462:12;:10;:12::i;:::-;128476:8;128486;128443:18;:52::i;:::-;128348:155;;:::o;129467:322::-;129641:41;129660:12;:10;:12::i;:::-;129674:7;129641:18;:41::i;:::-;129633:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;129743:38;129757:4;129763:2;129767:7;129776:4;129743:13;:38::i;:::-;129467:322;;;;:::o;116386:157::-;116471:4;116510:25;116495:40;;;:11;:40;;;;116488:47;;116386:157;;;:::o;124044:98::-;124097:7;124124:10;124117:17;;124044:98;:::o;137203:174::-;137305:2;137278:15;:24;137294:7;137278:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;137361:7;137357:2;137323:46;;137332:23;137347:7;137332:14;:23::i;:::-;137323:46;;;;;;;;;;;;137203:174;;:::o;131822:264::-;131915:4;131932:13;131948:23;131963:7;131948:14;:23::i;:::-;131932:39;;132001:5;131990:16;;:7;:16;;;:52;;;;132010:32;132027:5;132034:7;132010:16;:32::i;:::-;131990:52;:87;;;;132070:7;132046:31;;:20;132058:7;132046:11;:20::i;:::-;:31;;;131990:87;131982:96;;;131822:264;;;;:::o;135821:1263::-;135980:4;135953:31;;:23;135968:7;135953:14;:23::i;:::-;:31;;;135945:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;136059:1;136045:16;;:2;:16;;;136037:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;136115:42;136136:4;136142:2;136146:7;136155:1;136115:20;:42::i;:::-;136287:4;136260:31;;:23;136275:7;136260:14;:23::i;:::-;:31;;;136252:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;136405:15;:24;136421:7;136405:24;;;;;;;;;;;;136398:31;;;;;;;;;;;136900:1;136881:9;:15;136891:4;136881:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;136933:1;136916:9;:13;136926:2;136916:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;136975:2;136956:7;:16;136964:7;136956:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;137014:7;137010:2;136995:27;;137004:4;136995:27;;;;;;;;;;;;137035:41;137055:4;137061:2;137065:7;137074:1;137035:19;:41::i;:::-;135821:1263;;;:::o;132765:319::-;132894:18;132900:2;132904:7;132894:5;:18::i;:::-;132945:53;132976:1;132980:2;132984:7;132993:4;132945:22;:53::i;:::-;132923:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;132765:319;;;:::o;137520:315::-;137675:8;137666:17;;:5;:17;;;137658:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;137762:8;137724:18;:25;137743:5;137724:25;;;;;;;;;;;;;;;:35;137750:8;137724:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;137808:8;137786:41;;137801:5;137786:41;;;137818:8;137786:41;;;;;;:::i;:::-;;;;;;;;137520:315;;;:::o;130670:313::-;130826:28;130836:4;130842:2;130846:7;130826:9;:28::i;:::-;130873:47;130896:4;130902:2;130906:7;130915:4;130873:22;:47::i;:::-;130865:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;130670:313;;;;:::o;140208:410::-;140398:1;140386:9;:13;140382:229;;;140436:1;140420:18;;:4;:18;;;140416:87;;140478:9;140459;:15;140469:4;140459:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;140416:87;140535:1;140521:16;;:2;:16;;;140517:83;;140575:9;140558;:13;140568:2;140558:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;140517:83;140382:229;140208:410;;;;:::o;141340:158::-;;;;;:::o;133420:942::-;133514:1;133500:16;;:2;:16;;;133492:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;133573:16;133581:7;133573;:16::i;:::-;133572:17;133564:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;133635:48;133664:1;133668:2;133672:7;133681:1;133635:20;:48::i;:::-;133782:16;133790:7;133782;:16::i;:::-;133781:17;133773:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;134197:1;134180:9;:13;134190:2;134180:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;134241:2;134222:7;:16;134230:7;134222:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;134286:7;134282:2;134261:33;;134278:1;134261:33;;;;;;;;;;;;134307:47;134335:1;134339:2;134343:7;134352:1;134307:19;:47::i;:::-;133420:942;;:::o;138623:853::-;138777:4;138798:15;:2;:13;;;:15::i;:::-;138794:675;;;138850:2;138834:36;;;138871:12;:10;:12::i;:::-;138885:4;138891:7;138900:4;138834:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;138830:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139092:1;139075:6;:13;:18;139071:328;;139118:60;;;;;;;;;;:::i;:::-;;;;;;;;139071:328;139349:6;139343:13;139334:6;139330:2;139326:15;139319:38;138830:584;138966:41;;;138956:51;;;:6;:51;;;;138949:58;;;;;138794:675;139453:4;139446:11;;138623:853;;;;;;;:::o;105355:326::-;105415:4;105672:1;105650:7;:19;;;:23;105643:30;;105355:326;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:126::-;1555:7;1595:42;1588:5;1584:54;1573:65;;1518:126;;;:::o;1650:96::-;1687:7;1716:24;1734:5;1716:24;:::i;:::-;1705:35;;1650:96;;;:::o;1752:122::-;1825:24;1843:5;1825:24;:::i;:::-;1818:5;1815:35;1805:63;;1864:1;1861;1854:12;1805:63;1752:122;:::o;1880:139::-;1926:5;1964:6;1951:20;1942:29;;1980:33;2007:5;1980:33;:::i;:::-;1880:139;;;;:::o;2025:329::-;2084:6;2133:2;2121:9;2112:7;2108:23;2104:32;2101:119;;;2139:79;;:::i;:::-;2101:119;2259:1;2284:53;2329:7;2320:6;2309:9;2305:22;2284:53;:::i;:::-;2274:63;;2230:117;2025:329;;;;:::o;2360:86::-;2395:7;2435:4;2428:5;2424:16;2413:27;;2360:86;;;:::o;2452:112::-;2535:22;2551:5;2535:22;:::i;:::-;2530:3;2523:35;2452:112;;:::o;2570:214::-;2659:4;2697:2;2686:9;2682:18;2674:26;;2710:67;2774:1;2763:9;2759:17;2750:6;2710:67;:::i;:::-;2570:214;;;;:::o;2790:99::-;2842:6;2876:5;2870:12;2860:22;;2790:99;;;:::o;2895:169::-;2979:11;3013:6;3008:3;3001:19;3053:4;3048:3;3044:14;3029:29;;2895:169;;;;:::o;3070:246::-;3151:1;3161:113;3175:6;3172:1;3169:13;3161:113;;;3260:1;3255:3;3251:11;3245:18;3241:1;3236:3;3232:11;3225:39;3197:2;3194:1;3190:10;3185:15;;3161:113;;;3308:1;3299:6;3294:3;3290:16;3283:27;3132:184;3070:246;;;:::o;3322:102::-;3363:6;3414:2;3410:7;3405:2;3398:5;3394:14;3390:28;3380:38;;3322:102;;;:::o;3430:377::-;3518:3;3546:39;3579:5;3546:39;:::i;:::-;3601:71;3665:6;3660:3;3601:71;:::i;:::-;3594:78;;3681:65;3739:6;3734:3;3727:4;3720:5;3716:16;3681:65;:::i;:::-;3771:29;3793:6;3771:29;:::i;:::-;3766:3;3762:39;3755:46;;3522:285;3430:377;;;;:::o;3813:313::-;3926:4;3964:2;3953:9;3949:18;3941:26;;4013:9;4007:4;4003:20;3999:1;3988:9;3984:17;3977:47;4041:78;4114:4;4105:6;4041:78;:::i;:::-;4033:86;;3813:313;;;;:::o;4132:116::-;4202:21;4217:5;4202:21;:::i;:::-;4195:5;4192:32;4182:60;;4238:1;4235;4228:12;4182:60;4132:116;:::o;4254:133::-;4297:5;4335:6;4322:20;4313:29;;4351:30;4375:5;4351:30;:::i;:::-;4254:133;;;;:::o;4393:323::-;4449:6;4498:2;4486:9;4477:7;4473:23;4469:32;4466:119;;;4504:79;;:::i;:::-;4466:119;4624:1;4649:50;4691:7;4682:6;4671:9;4667:22;4649:50;:::i;:::-;4639:60;;4595:114;4393:323;;;;:::o;4722:77::-;4759:7;4788:5;4777:16;;4722:77;;;:::o;4805:122::-;4878:24;4896:5;4878:24;:::i;:::-;4871:5;4868:35;4858:63;;4917:1;4914;4907:12;4858:63;4805:122;:::o;4933:139::-;4979:5;5017:6;5004:20;4995:29;;5033:33;5060:5;5033:33;:::i;:::-;4933:139;;;;:::o;5078:329::-;5137:6;5186:2;5174:9;5165:7;5161:23;5157:32;5154:119;;;5192:79;;:::i;:::-;5154:119;5312:1;5337:53;5382:7;5373:6;5362:9;5358:22;5337:53;:::i;:::-;5327:63;;5283:117;5078:329;;;;:::o;5413:118::-;5500:24;5518:5;5500:24;:::i;:::-;5495:3;5488:37;5413:118;;:::o;5537:222::-;5630:4;5668:2;5657:9;5653:18;5645:26;;5681:71;5749:1;5738:9;5734:17;5725:6;5681:71;:::i;:::-;5537:222;;;;:::o;5765:474::-;5833:6;5841;5890:2;5878:9;5869:7;5865:23;5861:32;5858:119;;;5896:79;;:::i;:::-;5858:119;6016:1;6041:53;6086:7;6077:6;6066:9;6062:22;6041:53;:::i;:::-;6031:63;;5987:117;6143:2;6169:53;6214:7;6205:6;6194:9;6190:22;6169:53;:::i;:::-;6159:63;;6114:118;5765:474;;;;;:::o;6245:111::-;6297:7;6326:24;6344:5;6326:24;:::i;:::-;6315:35;;6245:111;;;:::o;6362:152::-;6450:39;6483:5;6450:39;:::i;:::-;6443:5;6440:50;6430:78;;6504:1;6501;6494:12;6430:78;6362:152;:::o;6520:169::-;6581:5;6619:6;6606:20;6597:29;;6635:48;6677:5;6635:48;:::i;:::-;6520:169;;;;:::o;6695:359::-;6769:6;6818:2;6806:9;6797:7;6793:23;6789:32;6786:119;;;6824:79;;:::i;:::-;6786:119;6944:1;6969:68;7029:7;7020:6;7009:9;7005:22;6969:68;:::i;:::-;6959:78;;6915:132;6695:359;;;;:::o;7060:619::-;7137:6;7145;7153;7202:2;7190:9;7181:7;7177:23;7173:32;7170:119;;;7208:79;;:::i;:::-;7170:119;7328:1;7353:53;7398:7;7389:6;7378:9;7374:22;7353:53;:::i;:::-;7343:63;;7299:117;7455:2;7481:53;7526:7;7517:6;7506:9;7502:22;7481:53;:::i;:::-;7471:63;;7426:118;7583:2;7609:53;7654:7;7645:6;7634:9;7630:22;7609:53;:::i;:::-;7599:63;;7554:118;7060:619;;;;;:::o;7685:474::-;7753:6;7761;7810:2;7798:9;7789:7;7785:23;7781:32;7778:119;;;7816:79;;:::i;:::-;7778:119;7936:1;7961:53;8006:7;7997:6;7986:9;7982:22;7961:53;:::i;:::-;7951:63;;7907:117;8063:2;8089:53;8134:7;8125:6;8114:9;8110:22;8089:53;:::i;:::-;8079:63;;8034:118;7685:474;;;;;:::o;8165:118::-;8252:24;8270:5;8252:24;:::i;:::-;8247:3;8240:37;8165:118;;:::o;8289:332::-;8410:4;8448:2;8437:9;8433:18;8425:26;;8461:71;8529:1;8518:9;8514:17;8505:6;8461:71;:::i;:::-;8542:72;8610:2;8599:9;8595:18;8586:6;8542:72;:::i;:::-;8289:332;;;;;:::o;8627:60::-;8655:3;8676:5;8669:12;;8627:60;;;:::o;8693:142::-;8743:9;8776:53;8794:34;8803:24;8821:5;8803:24;:::i;:::-;8794:34;:::i;:::-;8776:53;:::i;:::-;8763:66;;8693:142;;;:::o;8841:126::-;8891:9;8924:37;8955:5;8924:37;:::i;:::-;8911:50;;8841:126;;;:::o;8973:141::-;9038:9;9071:37;9102:5;9071:37;:::i;:::-;9058:50;;8973:141;;;:::o;9120:161::-;9222:52;9268:5;9222:52;:::i;:::-;9217:3;9210:65;9120:161;;:::o;9287:252::-;9395:4;9433:2;9422:9;9418:18;9410:26;;9446:86;9529:1;9518:9;9514:17;9505:6;9446:86;:::i;:::-;9287:252;;;;:::o;9545:222::-;9638:4;9676:2;9665:9;9661:18;9653:26;;9689:71;9757:1;9746:9;9742:17;9733:6;9689:71;:::i;:::-;9545:222;;;;:::o;9773:158::-;9855:9;9888:37;9919:5;9888:37;:::i;:::-;9875:50;;9773:158;;;:::o;9937:195::-;10056:69;10119:5;10056:69;:::i;:::-;10051:3;10044:82;9937:195;;:::o;10138:286::-;10263:4;10301:2;10290:9;10286:18;10278:26;;10314:103;10414:1;10403:9;10399:17;10390:6;10314:103;:::i;:::-;10138:286;;;;:::o;10430:118::-;10501:22;10517:5;10501:22;:::i;:::-;10494:5;10491:33;10481:61;;10538:1;10535;10528:12;10481:61;10430:118;:::o;10554:135::-;10598:5;10636:6;10623:20;10614:29;;10652:31;10677:5;10652:31;:::i;:::-;10554:135;;;;:::o;10695:325::-;10752:6;10801:2;10789:9;10780:7;10776:23;10772:32;10769:119;;;10807:79;;:::i;:::-;10769:119;10927:1;10952:51;10995:7;10986:6;10975:9;10971:22;10952:51;:::i;:::-;10942:61;;10898:115;10695:325;;;;:::o;11026:144::-;11094:9;11127:37;11158:5;11127:37;:::i;:::-;11114:50;;11026:144;;;:::o;11176:167::-;11281:55;11330:5;11281:55;:::i;:::-;11276:3;11269:68;11176:167;;:::o;11349:258::-;11460:4;11498:2;11487:9;11483:18;11475:26;;11511:89;11597:1;11586:9;11582:17;11573:6;11511:89;:::i;:::-;11349:258;;;;:::o;11613:468::-;11678:6;11686;11735:2;11723:9;11714:7;11710:23;11706:32;11703:119;;;11741:79;;:::i;:::-;11703:119;11861:1;11886:53;11931:7;11922:6;11911:9;11907:22;11886:53;:::i;:::-;11876:63;;11832:117;11988:2;12014:50;12056:7;12047:6;12036:9;12032:22;12014:50;:::i;:::-;12004:60;;11959:115;11613:468;;;;;:::o;12087:117::-;12196:1;12193;12186:12;12210:117;12319:1;12316;12309:12;12333:180;12381:77;12378:1;12371:88;12478:4;12475:1;12468:15;12502:4;12499:1;12492:15;12519:281;12602:27;12624:4;12602:27;:::i;:::-;12594:6;12590:40;12732:6;12720:10;12717:22;12696:18;12684:10;12681:34;12678:62;12675:88;;;12743:18;;:::i;:::-;12675:88;12783:10;12779:2;12772:22;12562:238;12519:281;;:::o;12806:129::-;12840:6;12867:20;;:::i;:::-;12857:30;;12896:33;12924:4;12916:6;12896:33;:::i;:::-;12806:129;;;:::o;12941:307::-;13002:4;13092:18;13084:6;13081:30;13078:56;;;13114:18;;:::i;:::-;13078:56;13152:29;13174:6;13152:29;:::i;:::-;13144:37;;13236:4;13230;13226:15;13218:23;;12941:307;;;:::o;13254:146::-;13351:6;13346:3;13341;13328:30;13392:1;13383:6;13378:3;13374:16;13367:27;13254:146;;;:::o;13406:423::-;13483:5;13508:65;13524:48;13565:6;13524:48;:::i;:::-;13508:65;:::i;:::-;13499:74;;13596:6;13589:5;13582:21;13634:4;13627:5;13623:16;13672:3;13663:6;13658:3;13654:16;13651:25;13648:112;;;13679:79;;:::i;:::-;13648:112;13769:54;13816:6;13811:3;13806;13769:54;:::i;:::-;13489:340;13406:423;;;;;:::o;13848:338::-;13903:5;13952:3;13945:4;13937:6;13933:17;13929:27;13919:122;;13960:79;;:::i;:::-;13919:122;14077:6;14064:20;14102:78;14176:3;14168:6;14161:4;14153:6;14149:17;14102:78;:::i;:::-;14093:87;;13909:277;13848:338;;;;:::o;14192:943::-;14287:6;14295;14303;14311;14360:3;14348:9;14339:7;14335:23;14331:33;14328:120;;;14367:79;;:::i;:::-;14328:120;14487:1;14512:53;14557:7;14548:6;14537:9;14533:22;14512:53;:::i;:::-;14502:63;;14458:117;14614:2;14640:53;14685:7;14676:6;14665:9;14661:22;14640:53;:::i;:::-;14630:63;;14585:118;14742:2;14768:53;14813:7;14804:6;14793:9;14789:22;14768:53;:::i;:::-;14758:63;;14713:118;14898:2;14887:9;14883:18;14870:32;14929:18;14921:6;14918:30;14915:117;;;14951:79;;:::i;:::-;14915:117;15056:62;15110:7;15101:6;15090:9;15086:22;15056:62;:::i;:::-;15046:72;;14841:287;14192:943;;;;;;;:::o;15141:474::-;15209:6;15217;15266:2;15254:9;15245:7;15241:23;15237:32;15234:119;;;15272:79;;:::i;:::-;15234:119;15392:1;15417:53;15462:7;15453:6;15442:9;15438:22;15417:53;:::i;:::-;15407:63;;15363:117;15519:2;15545:53;15590:7;15581:6;15570:9;15566:22;15545:53;:::i;:::-;15535:63;;15490:118;15141:474;;;;;:::o;15621:180::-;15669:77;15666:1;15659:88;15766:4;15763:1;15756:15;15790:4;15787:1;15780:15;15807:320;15851:6;15888:1;15882:4;15878:12;15868:22;;15935:1;15929:4;15925:12;15956:18;15946:81;;16012:4;16004:6;16000:17;15990:27;;15946:81;16074:2;16066:6;16063:14;16043:18;16040:38;16037:84;;16093:18;;:::i;:::-;16037:84;15858:269;15807:320;;;:::o;16133:89::-;16169:7;16209:6;16202:5;16198:18;16187:29;;16133:89;;;:::o;16228:115::-;16313:23;16330:5;16313:23;:::i;:::-;16308:3;16301:36;16228:115;;:::o;16349:328::-;16468:4;16506:2;16495:9;16491:18;16483:26;;16519:69;16585:1;16574:9;16570:17;16561:6;16519:69;:::i;:::-;16598:72;16666:2;16655:9;16651:18;16642:6;16598:72;:::i;:::-;16349:328;;;;;:::o;16683:147::-;16784:11;16821:3;16806:18;;16683:147;;;;:::o;16836:114::-;;:::o;16956:398::-;17115:3;17136:83;17217:1;17212:3;17136:83;:::i;:::-;17129:90;;17228:93;17317:3;17228:93;:::i;:::-;17346:1;17341:3;17337:11;17330:18;;16956:398;;;:::o;17360:379::-;17544:3;17566:147;17709:3;17566:147;:::i;:::-;17559:154;;17730:3;17723:10;;17360:379;;;:::o;17745:174::-;17885:26;17881:1;17873:6;17869:14;17862:50;17745:174;:::o;17925:366::-;18067:3;18088:67;18152:2;18147:3;18088:67;:::i;:::-;18081:74;;18164:93;18253:3;18164:93;:::i;:::-;18282:2;18277:3;18273:12;18266:19;;17925:366;;;:::o;18297:419::-;18463:4;18501:2;18490:9;18486:18;18478:26;;18550:9;18544:4;18540:20;18536:1;18525:9;18521:17;18514:47;18578:131;18704:4;18578:131;:::i;:::-;18570:139;;18297:419;;;:::o;18722:180::-;18770:77;18767:1;18760:88;18867:4;18864:1;18857:15;18891:4;18888:1;18881:15;18908:191;18948:3;18967:20;18985:1;18967:20;:::i;:::-;18962:25;;19001:20;19019:1;19001:20;:::i;:::-;18996:25;;19044:1;19041;19037:9;19030:16;;19065:3;19062:1;19059:10;19056:36;;;19072:18;;:::i;:::-;19056:36;18908:191;;;;:::o;19105:188::-;19143:3;19162:18;19178:1;19162:18;:::i;:::-;19157:23;;19194:18;19210:1;19194:18;:::i;:::-;19189:23;;19235:1;19232;19228:9;19221:16;;19258:4;19253:3;19250:13;19247:39;;;19266:18;;:::i;:::-;19247:39;19105:188;;;;:::o;19299:410::-;19339:7;19362:20;19380:1;19362:20;:::i;:::-;19357:25;;19396:20;19414:1;19396:20;:::i;:::-;19391:25;;19451:1;19448;19444:9;19473:30;19491:11;19473:30;:::i;:::-;19462:41;;19652:1;19643:7;19639:15;19636:1;19633:22;19613:1;19606:9;19586:83;19563:139;;19682:18;;:::i;:::-;19563:139;19347:362;19299:410;;;;:::o;19715:218::-;19806:4;19844:2;19833:9;19829:18;19821:26;;19857:69;19923:1;19912:9;19908:17;19899:6;19857:69;:::i;:::-;19715:218;;;;:::o;19939:167::-;19976:3;19999:22;20015:5;19999:22;:::i;:::-;19990:31;;20043:4;20036:5;20033:15;20030:41;;20051:18;;:::i;:::-;20030:41;20098:1;20091:5;20087:13;20080:20;;19939:167;;;:::o;20112:228::-;20252:34;20248:1;20240:6;20236:14;20229:58;20321:11;20316:2;20308:6;20304:15;20297:36;20112:228;:::o;20346:366::-;20488:3;20509:67;20573:2;20568:3;20509:67;:::i;:::-;20502:74;;20585:93;20674:3;20585:93;:::i;:::-;20703:2;20698:3;20694:12;20687:19;;20346:366;;;:::o;20718:419::-;20884:4;20922:2;20911:9;20907:18;20899:26;;20971:9;20965:4;20961:20;20957:1;20946:9;20942:17;20935:47;20999:131;21125:4;20999:131;:::i;:::-;20991:139;;20718:419;;;:::o;21143:178::-;21283:30;21279:1;21271:6;21267:14;21260:54;21143:178;:::o;21327:366::-;21469:3;21490:67;21554:2;21549:3;21490:67;:::i;:::-;21483:74;;21566:93;21655:3;21566:93;:::i;:::-;21684:2;21679:3;21675:12;21668:19;;21327:366;;;:::o;21699:419::-;21865:4;21903:2;21892:9;21888:18;21880:26;;21952:9;21946:4;21942:20;21938:1;21927:9;21923:17;21916:47;21980:131;22106:4;21980:131;:::i;:::-;21972:139;;21699:419;;;:::o;22124:143::-;22181:5;22212:6;22206:13;22197:22;;22228:33;22255:5;22228:33;:::i;:::-;22124:143;;;;:::o;22273:351::-;22343:6;22392:2;22380:9;22371:7;22367:23;22363:32;22360:119;;;22398:79;;:::i;:::-;22360:119;22518:1;22543:64;22599:7;22590:6;22579:9;22575:22;22543:64;:::i;:::-;22533:74;;22489:128;22273:351;;;;:::o;22630:180::-;22678:77;22675:1;22668:88;22775:4;22772:1;22765:15;22799:4;22796:1;22789:15;22816:185;22856:1;22873:20;22891:1;22873:20;:::i;:::-;22868:25;;22907:20;22925:1;22907:20;:::i;:::-;22902:25;;22946:1;22936:35;;22951:18;;:::i;:::-;22936:35;22993:1;22990;22986:9;22981:14;;22816:185;;;;:::o;23007:250::-;23147:34;23143:1;23135:6;23131:14;23124:58;23216:33;23211:2;23203:6;23199:15;23192:58;23007:250;:::o;23263:366::-;23405:3;23426:67;23490:2;23485:3;23426:67;:::i;:::-;23419:74;;23502:93;23591:3;23502:93;:::i;:::-;23620:2;23615:3;23611:12;23604:19;;23263:366;;;:::o;23635:419::-;23801:4;23839:2;23828:9;23824:18;23816:26;;23888:9;23882:4;23878:20;23874:1;23863:9;23859:17;23852:47;23916:131;24042:4;23916:131;:::i;:::-;23908:139;;23635:419;;;:::o;24060:168::-;24200:20;24196:1;24188:6;24184:14;24177:44;24060:168;:::o;24234:366::-;24376:3;24397:67;24461:2;24456:3;24397:67;:::i;:::-;24390:74;;24473:93;24562:3;24473:93;:::i;:::-;24591:2;24586:3;24582:12;24575:19;;24234:366;;;:::o;24606:419::-;24772:4;24810:2;24799:9;24795:18;24787:26;;24859:9;24853:4;24849:20;24845:1;24834:9;24830:17;24823:47;24887:131;25013:4;24887:131;:::i;:::-;24879:139;;24606:419;;;:::o;25031:170::-;25171:22;25167:1;25159:6;25155:14;25148:46;25031:170;:::o;25207:366::-;25349:3;25370:67;25434:2;25429:3;25370:67;:::i;:::-;25363:74;;25446:93;25535:3;25446:93;:::i;:::-;25564:2;25559:3;25555:12;25548:19;;25207:366;;;:::o;25579:419::-;25745:4;25783:2;25772:9;25768:18;25760:26;;25832:9;25826:4;25822:20;25818:1;25807:9;25803:17;25796:47;25860:131;25986:4;25860:131;:::i;:::-;25852:139;;25579:419;;;:::o;26004:308::-;26066:4;26156:18;26148:6;26145:30;26142:56;;;26178:18;;:::i;:::-;26142:56;26216:29;26238:6;26216:29;:::i;:::-;26208:37;;26300:4;26294;26290:15;26282:23;;26004:308;;;:::o;26318:434::-;26407:5;26432:66;26448:49;26490:6;26448:49;:::i;:::-;26432:66;:::i;:::-;26423:75;;26521:6;26514:5;26507:21;26559:4;26552:5;26548:16;26597:3;26588:6;26583:3;26579:16;26576:25;26573:112;;;26604:79;;:::i;:::-;26573:112;26694:52;26739:6;26734:3;26729;26694:52;:::i;:::-;26413:339;26318:434;;;;;:::o;26772:355::-;26839:5;26888:3;26881:4;26873:6;26869:17;26865:27;26855:122;;26896:79;;:::i;:::-;26855:122;27006:6;27000:13;27031:90;27117:3;27109:6;27102:4;27094:6;27090:17;27031:90;:::i;:::-;27022:99;;26845:282;26772:355;;;;:::o;27133:524::-;27213:6;27262:2;27250:9;27241:7;27237:23;27233:32;27230:119;;;27268:79;;:::i;:::-;27230:119;27409:1;27398:9;27394:17;27388:24;27439:18;27431:6;27428:30;27425:117;;;27461:79;;:::i;:::-;27425:117;27566:74;27632:7;27623:6;27612:9;27608:22;27566:74;:::i;:::-;27556:84;;27359:291;27133:524;;;;:::o;27663:225::-;27803:34;27799:1;27791:6;27787:14;27780:58;27872:8;27867:2;27859:6;27855:15;27848:33;27663:225;:::o;27894:366::-;28036:3;28057:67;28121:2;28116:3;28057:67;:::i;:::-;28050:74;;28133:93;28222:3;28133:93;:::i;:::-;28251:2;28246:3;28242:12;28235:19;;27894:366;;;:::o;28266:419::-;28432:4;28470:2;28459:9;28455:18;28447:26;;28519:9;28513:4;28509:20;28505:1;28494:9;28490:17;28483:47;28547:131;28673:4;28547:131;:::i;:::-;28539:139;;28266:419;;;:::o;28691:182::-;28831:34;28827:1;28819:6;28815:14;28808:58;28691:182;:::o;28879:366::-;29021:3;29042:67;29106:2;29101:3;29042:67;:::i;:::-;29035:74;;29118:93;29207:3;29118:93;:::i;:::-;29236:2;29231:3;29227:12;29220:19;;28879:366;;;:::o;29251:419::-;29417:4;29455:2;29444:9;29440:18;29432:26;;29504:9;29498:4;29494:20;29490:1;29479:9;29475:17;29468:47;29532:131;29658:4;29532:131;:::i;:::-;29524:139;;29251:419;;;:::o;29676:332::-;29797:4;29835:2;29824:9;29820:18;29812:26;;29848:71;29916:1;29905:9;29901:17;29892:6;29848:71;:::i;:::-;29929:72;29997:2;29986:9;29982:18;29973:6;29929:72;:::i;:::-;29676:332;;;;;:::o;30014:137::-;30068:5;30099:6;30093:13;30084:22;;30115:30;30139:5;30115:30;:::i;:::-;30014:137;;;;:::o;30157:345::-;30224:6;30273:2;30261:9;30252:7;30248:23;30244:32;30241:119;;;30279:79;;:::i;:::-;30241:119;30399:1;30424:61;30477:7;30468:6;30457:9;30453:22;30424:61;:::i;:::-;30414:71;;30370:125;30157:345;;;;:::o;30508:220::-;30648:34;30644:1;30636:6;30632:14;30625:58;30717:3;30712:2;30704:6;30700:15;30693:28;30508:220;:::o;30734:366::-;30876:3;30897:67;30961:2;30956:3;30897:67;:::i;:::-;30890:74;;30973:93;31062:3;30973:93;:::i;:::-;31091:2;31086:3;31082:12;31075:19;;30734:366;;;:::o;31106:419::-;31272:4;31310:2;31299:9;31295:18;31287:26;;31359:9;31353:4;31349:20;31345:1;31334:9;31330:17;31323:47;31387:131;31513:4;31387:131;:::i;:::-;31379:139;;31106:419;;;:::o;31531:248::-;31671:34;31667:1;31659:6;31655:14;31648:58;31740:31;31735:2;31727:6;31723:15;31716:56;31531:248;:::o;31785:366::-;31927:3;31948:67;32012:2;32007:3;31948:67;:::i;:::-;31941:74;;32024:93;32113:3;32024:93;:::i;:::-;32142:2;32137:3;32133:12;32126:19;;31785:366;;;:::o;32157:419::-;32323:4;32361:2;32350:9;32346:18;32338:26;;32410:9;32404:4;32400:20;32396:1;32385:9;32381:17;32374:47;32438:131;32564:4;32438:131;:::i;:::-;32430:139;;32157:419;;;:::o;32582:232::-;32722:34;32718:1;32710:6;32706:14;32699:58;32791:15;32786:2;32778:6;32774:15;32767:40;32582:232;:::o;32820:366::-;32962:3;32983:67;33047:2;33042:3;32983:67;:::i;:::-;32976:74;;33059:93;33148:3;33059:93;:::i;:::-;33177:2;33172:3;33168:12;33161:19;;32820:366;;;:::o;33192:419::-;33358:4;33396:2;33385:9;33381:18;33373:26;;33445:9;33439:4;33435:20;33431:1;33420:9;33416:17;33409:47;33473:131;33599:4;33473:131;:::i;:::-;33465:139;;33192:419;;;:::o;33617:224::-;33757:34;33753:1;33745:6;33741:14;33734:58;33826:7;33821:2;33813:6;33809:15;33802:32;33617:224;:::o;33847:366::-;33989:3;34010:67;34074:2;34069:3;34010:67;:::i;:::-;34003:74;;34086:93;34175:3;34086:93;:::i;:::-;34204:2;34199:3;34195:12;34188:19;;33847:366;;;:::o;34219:419::-;34385:4;34423:2;34412:9;34408:18;34400:26;;34472:9;34466:4;34462:20;34458:1;34447:9;34443:17;34436:47;34500:131;34626:4;34500:131;:::i;:::-;34492:139;;34219:419;;;:::o;34644:223::-;34784:34;34780:1;34772:6;34768:14;34761:58;34853:6;34848:2;34840:6;34836:15;34829:31;34644:223;:::o;34873:366::-;35015:3;35036:67;35100:2;35095:3;35036:67;:::i;:::-;35029:74;;35112:93;35201:3;35112:93;:::i;:::-;35230:2;35225:3;35221:12;35214:19;;34873:366;;;:::o;35245:419::-;35411:4;35449:2;35438:9;35434:18;35426:26;;35498:9;35492:4;35488:20;35484:1;35473:9;35469:17;35462:47;35526:131;35652:4;35526:131;:::i;:::-;35518:139;;35245:419;;;:::o;35670:237::-;35810:34;35806:1;35798:6;35794:14;35787:58;35879:20;35874:2;35866:6;35862:15;35855:45;35670:237;:::o;35913:366::-;36055:3;36076:67;36140:2;36135:3;36076:67;:::i;:::-;36069:74;;36152:93;36241:3;36152:93;:::i;:::-;36270:2;36265:3;36261:12;36254:19;;35913:366;;;:::o;36285:419::-;36451:4;36489:2;36478:9;36474:18;36466:26;;36538:9;36532:4;36528:20;36524:1;36513:9;36509:17;36502:47;36566:131;36692:4;36566:131;:::i;:::-;36558:139;;36285:419;;;:::o;36710:175::-;36850:27;36846:1;36838:6;36834:14;36827:51;36710:175;:::o;36891:366::-;37033:3;37054:67;37118:2;37113:3;37054:67;:::i;:::-;37047:74;;37130:93;37219:3;37130:93;:::i;:::-;37248:2;37243:3;37239:12;37232:19;;36891:366;;;:::o;37263:419::-;37429:4;37467:2;37456:9;37452:18;37444:26;;37516:9;37510:4;37506:20;37502:1;37491:9;37487:17;37480:47;37544:131;37670:4;37544:131;:::i;:::-;37536:139;;37263:419;;;:::o;37688:194::-;37728:4;37748:20;37766:1;37748:20;:::i;:::-;37743:25;;37782:20;37800:1;37782:20;:::i;:::-;37777:25;;37826:1;37823;37819:9;37811:17;;37850:1;37844:4;37841:11;37838:37;;;37855:18;;:::i;:::-;37838:37;37688:194;;;;:::o;37888:182::-;38028:34;38024:1;38016:6;38012:14;38005:58;37888:182;:::o;38076:366::-;38218:3;38239:67;38303:2;38298:3;38239:67;:::i;:::-;38232:74;;38315:93;38404:3;38315:93;:::i;:::-;38433:2;38428:3;38424:12;38417:19;;38076:366;;;:::o;38448:419::-;38614:4;38652:2;38641:9;38637:18;38629:26;;38701:9;38695:4;38691:20;38687:1;38676:9;38672:17;38665:47;38729:131;38855:4;38729:131;:::i;:::-;38721:139;;38448:419;;;:::o;38873:178::-;39013:30;39009:1;39001:6;38997:14;38990:54;38873:178;:::o;39057:366::-;39199:3;39220:67;39284:2;39279:3;39220:67;:::i;:::-;39213:74;;39296:93;39385:3;39296:93;:::i;:::-;39414:2;39409:3;39405:12;39398:19;;39057:366;;;:::o;39429:419::-;39595:4;39633:2;39622:9;39618:18;39610:26;;39682:9;39676:4;39672:20;39668:1;39657:9;39653:17;39646:47;39710:131;39836:4;39710:131;:::i;:::-;39702:139;;39429:419;;;:::o;39854:98::-;39905:6;39939:5;39933:12;39923:22;;39854:98;;;:::o;39958:168::-;40041:11;40075:6;40070:3;40063:19;40115:4;40110:3;40106:14;40091:29;;39958:168;;;;:::o;40132:373::-;40218:3;40246:38;40278:5;40246:38;:::i;:::-;40300:70;40363:6;40358:3;40300:70;:::i;:::-;40293:77;;40379:65;40437:6;40432:3;40425:4;40418:5;40414:16;40379:65;:::i;:::-;40469:29;40491:6;40469:29;:::i;:::-;40464:3;40460:39;40453:46;;40222:283;40132:373;;;;:::o;40511:640::-;40706:4;40744:3;40733:9;40729:19;40721:27;;40758:71;40826:1;40815:9;40811:17;40802:6;40758:71;:::i;:::-;40839:72;40907:2;40896:9;40892:18;40883:6;40839:72;:::i;:::-;40921;40989:2;40978:9;40974:18;40965:6;40921:72;:::i;:::-;41040:9;41034:4;41030:20;41025:2;41014:9;41010:18;41003:48;41068:76;41139:4;41130:6;41068:76;:::i;:::-;41060:84;;40511:640;;;;;;;:::o;41157:141::-;41213:5;41244:6;41238:13;41229:22;;41260:32;41286:5;41260:32;:::i;:::-;41157:141;;;;:::o;41304:349::-;41373:6;41422:2;41410:9;41401:7;41397:23;41393:32;41390:119;;;41428:79;;:::i;:::-;41390:119;41548:1;41573:63;41628:7;41619:6;41608:9;41604:22;41573:63;:::i;:::-;41563:73;;41519:127;41304:349;;;;:::o

Swarm Source

ipfs://e7abc160bf11af6d8e4949a33509fb1ce2bd68f6f074c66258f8f529a6b3ed53
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.