// File: SDPResolver.sol



/*5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555555555555PPPPP5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555555PPPP555YYJJJJYYY555PPPPP555555555555555555555555555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555555555555555PPP5Y?!~^::............::~!?Y555YYYY55555555555555555555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555555555555PP5J!^:...........     ....     :~~^:.^JP555555555555555555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555555555PP5?^.........  ....:^~!7?JYY~..^!?7~.::^!?YPP5555555555555555555555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555555555555P5J^........  ..:^^~7?Y55PP5J!~!7?JJ~:.  .....:75555YYYYY5555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555P57:........ .:~~~~?Y5PPPPPY7~~7?????:~55?:      .:!!~^^^:^YPPPPP5555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555P57......... .^!~~7Y5P555P5J~~!??7!7??:?P5J7!:^~!7??!^::7JYYYJJJJJJJJYY55PP55555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555PJ^:::.. .. .~!^~?5P5555P5?~~7?777!7?J.!J~^~7??JJ?J~.    :!!!!777777777!!77?Y5PPPPPP555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555P5~.!??!~^^: :!^^JPPPPPP557^!7777??77???~~~7?????????!^~!77???????????777!!!!~^^7?7!~~J55555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555PY:.......::.!~:?P5P5J!^.. .~7??????77??777???????????JJJ??????77!!!!!77JJY?!777?7^^!?Y555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555PY..:......  !:~5PY5^      ~@@^7??????7?JY?!7?????777??7777??!!!7?Y5PPB&&BP5J77!7??!!~^5555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555PY.........  ^:?PJJ#@.      YB: :YP!??????5J7777??J5GB5?77?7!!7J5PP5J5BB5?77777777??J!^?5555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555.......... ::YYJ#@@@&#P.  !#BB&@@@Y7??????YYJJY5GBGY?7???7!7J5PY?7Y#BY7777!!7??JJJ??:7P5555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555P^.:....... .:5J5@@@@@#! .?&@@@@@@@@B~77??J???JPGPY?7?????!7?YPY7!Y##Y7!!!7JYPPP5YJ77?7:J5555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555P? ........ ..YJP@@@@@@!^P@@&?B@@@@@@P 7#B?~7?5&57!7??????!7J557!5##J77J5GBBG5Y?7777?7!~:!P555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555.........  ..:.5PG@@@&7G#BJ^:JBB&@@@!!PG?  .~~GGGG5J!7??!7J5?!5&&GPB##BPY?777777!~~~~7J5P5555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555P! :....... ..:::. !@&5^::::::^:7B@@P.         :?J?J5#PY5?7JJ75&@@#BPY?77!!~~~~~!!7JY5PPP555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555P? ........  .^^::::.:.^5~:::^^:P@@J  :^      .@@G. :5:~!!?J?75&GJ7!!!!~^.^7?JY55PPPP55555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555PP7.......... ..:^~:::::.Y@?^~~:::BP. .5&Y .    ~&~ .?&@.    ^7?777777!:.    7PPP55555555P55555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555PJ:...........  :^::~:::^~:5@@B!:!B@@@&@@@@@B:  7&@&@@@&&@&?  .?YGPPPB###G:  ^^7JJJJJJJJJ?JP5555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555P!  .:^:.  .... .:.^!^~.^~^::Y!:~P&@&&&&&&&&P~~!P&##&&###B#G55P#####&#&#&&##&&&&&&&&&&&&&&G~P5555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555P7 .!777??7:  .. ^J~.~7^~:~::~.?JB&&&&&&&&&&&&&&@&&@@@@@@@@@@@@@@@&&@@@@&GPP5YJJJJJ?????G@@P!P5555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555 .?7^~!!~7J7. .. 7Y!.7!^:^..^:?7B&&&&&B5YY?!!!!~~~~~^^!!P@@@@&&&&&@@@@B::~~~~!::!~!!7!~ G@5!P5555555555555555555555555555555555555555555555
555555555555555555555555555555555555555P7 !?:.!~!J77J?... :JY~^?^^::.:^.~#&&&&7^~^^::^^:...:7JYG!.P@@@@&&&&&@@@?.:^75PY~P???7!!!.P@Y7P5555555555555555555555555555555555555555555555
555555555555555555555555555555555555555P~ 77.^^~^^P?7Y: .. YY?^?^^.:::^.~&&&&G.77??J?^^. .:^^?5J::5@@@@&&&&&&&@!:::^557?PJ?!!!7~.#@??P5555555555555555555555555555555555555555555555
555555555555555555555555555555555555555P! !7.^^!7:5J7Y^ .. JP5^7~^.:^~^.!&&&&5.!7???^:..^^:.:^?~.^B@@#!.  .:#&&^~^:J?:.:7!~~~~~^!&@7?P5555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555Y .?!^^~^!J77Y: .. JPP~7~^.~~~^^7&&&&?~7!!7?Y~:!7:...:^:^~#@&:!7?J5..&&G~~!7~~!!??JYY5PB@@#~555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555P? :??!~!7!7?! .. .5PJ~?^:.~~~..J&&&&5:!7!~~!~:......^^~7G@@^5@@@@@# ?&&&&&&&&&&&&&&##BBPJ7Y555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555PJ..~7?777!^.... 7G5~77^.^~~::.J&&&&&GJJJYYYPGGBB##&&&&@&B!5@@@@@@@#!7557Y55?::7?????JJY5P5555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555P57....... .. .?PJ!7?~:.~~^.~:.G&&&&&&&&&&&&@&&##BGP55J~?B&&&@@@@@@@&&Y^...   .JP555P55555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555P5J~  ....:~7J777?!:.^^:.:^::..^~JPG5~:::.. ^5GBB#&&~  .7B&&@@@@@@@?  ~7     :Y555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555PP57^^!!77777?7^.....:J&!::^.  5@5.  Y! ^P&@@@@@@@B?PP5P&@@@@@@@@BP#&@B^  7P^P55555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555P5J!^~!!7~:. !PYYP&@@G5Y:   PJ^~?GGP#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&5.^J:555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555PP7J@#!  ^B@@@@@@@@@B^  7B#BBB#&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#7~:5P5555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555555Y~&  ^#@@P@@@&&&&~  ~G###&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&G^^?55PPP55555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555555P7~:B@@J  &&B&&&&#&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&G?~~!7JY5PP5555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555P~        .&@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&@@@@&G5?~^~7YP55555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555P7      J&&@&&#G5G#&&&@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&#BPY?7!!77J5G&@@@@@&G?^^5P555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555555555PY^    @G.J&@@@&BY?YG&&&@@@@@@@@@@@@@@@@@@@@@@&&&&&&#G5JJY5PGGBBB#########&&@@&7.Y555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555555PY~ :#5YG&&&&@@@&BJ!?5#&&@@@@@@@@@@@@@@@@@@@&&&#GPGB#&&&&&&&&&&&&&&&&&&&&&@@@@:^P55555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555P5JYB@@@@&G7Y#@@@&BY!~?5B&&@@@@@@@@@@@@@@@@@&&&@@@&@@@@&&##BBBBBB###&&&&@&&B.~P55555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555555555555J?5&@@^ :G#GB&@@@&GJ!~!7J5GB&&@@@@@@@@@@@@@@@@@&&BP55PGB##&&&######B??~:!5555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555Y?JB^Y#B7  !5P&@@@@&#BP5J?7!7JPB&@@@@@@@@@&#PJYPB&@@@@@@@@@@@@@@@G !J5P5555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555555555555555P57        .7BBY5#&@@@@@@@&&BPJ??J5GBBGPYJYG&@@@@&BPYJ??7??JYPGP::PP555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555P~      ^@@P:  . :~?YPB#&@@@@@&#GPPPPB#&@@&#Y!^^^~!7?????77!~~?555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555P!      PB:  ?@J      .J..~YPB&@@@@@@@@#P7^^!?Y5PPPPPPPPPPPPPPP555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555P!5P.  !&#B&@@@@&B~  .B&BGBG:7!!7?JJ?!~^!?5PPP55555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555P!.  7&@@@@@@@@@J  ^B@@@@@@&~PP5YJJJJY5PPP555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555555555555P! Y@@#^G@@@@@@P ~#@@?~@@@@&~P5555PP555555555555555555555555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555555555555555555555PP7!G5^  ~55&@@@7!PG?  .P5G@&~PP55555555555555555555555555555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555555555555555555PP5Y?^       :P@@P.         7&@5:?JY5PPP555555555555555555555555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555555555555555P5Y!.  7       ?@@5. :~      .@@B:  7   :~?Y5P555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555PY!?^  7&@: .    5P. :G@G      ^#^ .?@@. .    ~?Y55555555555555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555555PY!?B&@@@@@@@&Y  .5@&&@@@@@@B~  !&@&@@@@@@&?  :G@&57JP55555555555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555555??#@@@@@@@@@P. .P@@@@@@@@@&^  ?&@@@@@@@@@J  ^B@@@@@@57YP555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555Y&@&!.@@@@@@@::B@@P.5@@@&BG~ .7557:PG#&&@@ ~&@@J &@@@@&?JP55555555555555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555555555:^?~   !75@@@G.7?!.  :77!?5B&@@@@@@@&#BG55J~?7~   ~7Y&@@# 7P5555555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555555:       .P@@G:        .J#@@@@@@@@@@@@@@@@@@@@#P7.   J@@#~   7P555555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555557J       @@5. .P.    :G@@@@@@@@@@@@@@@@@@@@@@@@@@@#~Y@B:  Y^  ?P55555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555P!#&:::   .&!.:P@@7. .G@@@@@@@@@@@@@@@@@@@@@@@@@@@@P.~~~.:J@@Y:::Y55555555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555PJY@@@B^  J@@@@@@@@B:J@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@YJ@@@@@@@@@5 :P5555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555555!@@@:  Y@@#@@@@@@7:#@@@@@@@@@@@@@@@@&@@@@@@@@@@@@@@@@BG@@@@@@P  ^!?P555555555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555PJP@@#.5@@B. @@@@&:!@@@@@@@@@@@@@@@@@@##@@@@@@@@@@&@@&&@&G@@@@@7^#@#^P555555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555557@@&:.^:.   :^PG.G@@@@@@@@@@@@@@@@@@@@GP@@@@@@@@@@@@@@G!.?@@@P.:^:  Y555555555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555YY#^         ^B7 77J5Y5@@@@@@@@@@@@@@@@@BJ&@@@@@@@@@@@@@~B@@Y.       !P55555555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555555P!   YP      .#.   .&@&~@@@@@@@@@@@@@@@@@@#^5@@@@@@@@@@@@&&J  .B~     .P55555555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555555^!5&@&7?~   :G!!J#P@@&?@@&&@@@@@@@@@@&PYJYP#@@@@@@@@@@@@&!~?B@@P!7:   7P5555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555P7G@@@@@@Y. :G@@@@@@P@@@##&@@@@@@@@@@@@G.!#@@@@@@@@@@@@@@@@#@@@@@@&7  7&7JP555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555Y7@@@@@&  ^#@G5@@@@@P@@@@@@@@@@@@@@@@@@@@P^7&@@@@@@@@@@@@@@B@@@@@Y  ?@@&P7YP55555555555555555555555555555555555555555555555555555555
55555555555555555555555555555555555555555555555P~B@@@@@B:B@@J  &@@@@G@@@@@@@@@@@@@@@@@@@@@Y.G@@@@@@@@@@@@@&G@@@@@7~&@#~ ~&~JP5555555555555555555555555555555555555555555555555555555
5555555555555555555555555555555555555555555555P7  ^B@@P. .     .:5@@G@@@@@@@@@@@@@@@@@@@@Y5@@@@@@@@@@@@@@@B 7@@&7 ..      ^7JP555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555P? .B@@Y. .       .#@B^ #@@@@@@@@@@@@@@@@@@@&@@@@@@@@@@@@@@@@5&@&!         .B@@^^5P5555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555~  7@Y  .BB      .57^  ?#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&G&~  ~B.      !@5. .7J55555555555555555555555555555555555555555555555555*/

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.2;

import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@ensdomains/ens-contracts/contracts/registry/ENS.sol";

contract DefaultReverseResolver {

	mapping (bytes32 => string) public name;

}

contract SDPResolver {

	using Strings for uint256;
	string public parentLabel = "slackerduck";
	mapping(bytes32 => uint256) public nodeToId;
	ENS constant private ens = ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
	IERC721 constant public nft = IERC721(0xeC516eFECd8276Efc608EcD958a4eAB8618c61e8);
	bytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;
	DefaultReverseResolver constant public reverseResolver = DefaultReverseResolver(0xA2C122BE93b0074270ebeE7f6b7292C7deB45047);

	function supportsInterface(bytes4 interfaceID) public pure returns (bool) {
		return interfaceID == 0x3b3b57de || interfaceID == 0x691f3431 || interfaceID == 0x59d1d43c || interfaceID == 0x01ffc9a7;
	}

	function addr(bytes32 node) public view returns (address) {
		return nft.ownerOf(nodeToId[node]);
	}

	function addressToBytes(address a) internal pure returns(bytes memory b) {
		b = new bytes(20);
		assembly {
			mstore(add(b, 32), mul(a, exp(256, 12)))
		}
	}

	function addr(bytes32 node, uint coinType) public view returns(bytes memory) {
		if(coinType == 60){
			return addressToBytes(nft.ownerOf(nodeToId[node]));
		}
	}

	function name(bytes32 node) view public returns (string memory){
		return string(abi.encodePacked(nodeToId[node].toString(), ".", parentLabel, ".eth"));
	}

	function text(bytes32 node, string calldata key) external view returns (string memory) {
		if(keccak256(abi.encodePacked(key)) == keccak256("url")){
			return "www.slackerduckpond.com";
		}
		if(keccak256(abi.encodePacked(key)) == keccak256("avatar")){
			return string(abi.encodePacked("eip155:1/erc721:0xec516efecd8276efc608ecd958a4eab8618c61e8/", nodeToId[node].toString()));
		}
		if(keccak256(abi.encodePacked(key)) == keccak256("description")){
			return "Each Slacker Duck is unique and programmatically generated from over 125 possible assets, such as expression, clothing, and more.";
		}
		if(keccak256(abi.encodePacked(key)) == keccak256("com.discord")){
			return "https://slackerduckpond.com/discord";
		}
		if(keccak256(abi.encodePacked(key)) == keccak256("com.twitter")){
			return "SlackerDuckPond";
		}
	}

	function sha3HexAddress(address a) private pure returns (bytes32 ret) {
		a;
		ret;
		assembly {
			let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000

			for { let i := 40 } gt(i, 0) { } {
				i := sub(i, 1)
				mstore8(i, byte(and(a, 0xf), lookup))
				a := div(a, 0x10)
				i := sub(i, 1)
				mstore8(i, byte(and(a, 0xf), lookup))
				a := div(a, 0x10)
			}

			ret := keccak256(0, 40)
		}
	}

	function claimed(uint256 tokenId) public view returns (bool) {
		bytes32 label = keccak256(abi.encodePacked(tokenId.toString()));
		bytes32 labelNode = keccak256(abi.encodePacked(parentNode(), label));
		return nodeToId[labelNode] > 0;
	}

	function primary(uint256 tokenId) public view returns (bool) {
		bytes32 label = keccak256(abi.encodePacked(tokenId.toString()));
		bytes32 labelNode = keccak256(abi.encodePacked(parentNode(), label));
		bytes32 reverseNode = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(nft.ownerOf(tokenId))));
		return keccak256(abi.encodePacked(reverseResolver.name(reverseNode))) == keccak256(abi.encodePacked(nodeToId[labelNode].toString(), ".", parentLabel, ".eth"));
	}

	function parentNode() private view returns (bytes32 node) {
		node = 0x0;
		node = keccak256(abi.encodePacked(node, keccak256(abi.encodePacked("eth"))));
		node = keccak256(abi.encodePacked(node, keccak256(abi.encodePacked(parentLabel))));
	}

	function claimSubdomain(uint256 tokenId) public onlyOwner(tokenId) {
		bytes32 label = keccak256(abi.encodePacked(tokenId.toString()));
		bytes32 labelNode = keccak256(abi.encodePacked(parentNode(), label));
		ens.setSubnodeRecord(parentNode(), label, address(this), address(this), 0);
		nodeToId[labelNode] = tokenId;
	}

	modifier onlyOwner(uint256 tokenId) {
		require(nft.ownerOf(tokenId) == msg.sender);
		_;
	}
}
// File: @ensdomains/ens-contracts/contracts/registry/ENS.sol



pragma solidity >=0.8.4;

interface ENS {
    // Logged when the owner of a node assigns a new owner to a subnode.
    event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);

    // Logged when the owner of a node transfers ownership to a new account.
    event Transfer(bytes32 indexed node, address owner);

    // Logged when the resolver for a node changes.
    event NewResolver(bytes32 indexed node, address resolver);

    // Logged when the TTL of a node changes
    event NewTTL(bytes32 indexed node, uint64 ttl);

    // Logged when an operator is added or removed.
    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );

    function setRecord(
        bytes32 node,
        address owner,
        address resolver,
        uint64 ttl
    ) external;

    function setSubnodeRecord(
        bytes32 node,
        bytes32 label,
        address owner,
        address resolver,
        uint64 ttl
    ) external;

    function setSubnodeOwner(
        bytes32 node,
        bytes32 label,
        address owner
    ) external returns (bytes32);

    function setResolver(bytes32 node, address resolver) external;

    function setOwner(bytes32 node, address owner) external;

    function setTTL(bytes32 node, uint64 ttl) external;

    function setApprovalForAll(address operator, bool approved) external;

    function owner(bytes32 node) external view returns (address);

    function resolver(bytes32 node) external view returns (address);

    function ttl(bytes32 node) external view returns (uint64);

    function recordExists(bytes32 node) external view returns (bool);

    function isApprovedForAll(address owner, address operator)
        external
        view
        returns (bool);
}

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



// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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

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



// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_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) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

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

    /**
     * @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/introspection/IERC165.sol



// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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