{
  "address": "0xa5627AB7Ae47063B533622C34FEBDb52d3281dF8",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "contract BaseRegistrarImplementation",
          "name": "_base",
          "type": "address"
        },
        {
          "internalType": "contract IPriceOracle",
          "name": "_prices",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_minCommitmentAge",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_maxCommitmentAge",
          "type": "uint256"
        },
        {
          "internalType": "contract ReverseRegistrar",
          "name": "_reverseRegistrar",
          "type": "address"
        },
        {
          "internalType": "contract INameWrapper",
          "name": "_nameWrapper",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        }
      ],
      "name": "CommitmentTooNew",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        }
      ],
      "name": "CommitmentTooOld",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        }
      ],
      "name": "DurationTooShort",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InsufficientValue",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "MaxCommitmentAgeTooHigh",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "MaxCommitmentAgeTooLow",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        }
      ],
      "name": "NameNotAvailable",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ResolverRequiredWhenDataSupplied",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        }
      ],
      "name": "Unauthorised",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        }
      ],
      "name": "UnexpiredCommitmentExists",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "string",
          "name": "name",
          "type": "string"
        },
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "label",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "baseCost",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "premium",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "expires",
          "type": "uint256"
        }
      ],
      "name": "NameRegistered",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "string",
          "name": "name",
          "type": "string"
        },
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "label",
          "type": "bytes32"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "cost",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "expires",
          "type": "uint256"
        }
      ],
      "name": "NameRenewed",
      "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"
    },
    {
      "inputs": [],
      "name": "MIN_REGISTRATION_DURATION",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        }
      ],
      "name": "available",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "commitment",
          "type": "bytes32"
        }
      ],
      "name": "commit",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "name": "commitments",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        },
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        },
        {
          "internalType": "bytes32",
          "name": "secret",
          "type": "bytes32"
        },
        {
          "internalType": "address",
          "name": "resolver",
          "type": "address"
        },
        {
          "internalType": "bytes[]",
          "name": "data",
          "type": "bytes[]"
        },
        {
          "internalType": "bool",
          "name": "reverseRecord",
          "type": "bool"
        },
        {
          "internalType": "uint32",
          "name": "fuses",
          "type": "uint32"
        },
        {
          "internalType": "uint64",
          "name": "wrapperExpiry",
          "type": "uint64"
        }
      ],
      "name": "makeCommitment",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "maxCommitmentAge",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "minCommitmentAge",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "nameWrapper",
      "outputs": [
        {
          "internalType": "contract INameWrapper",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "prices",
      "outputs": [
        {
          "internalType": "contract IPriceOracle",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_token",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_to",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amount",
          "type": "uint256"
        }
      ],
      "name": "recoverFunds",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        },
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        },
        {
          "internalType": "bytes32",
          "name": "secret",
          "type": "bytes32"
        },
        {
          "internalType": "address",
          "name": "resolver",
          "type": "address"
        },
        {
          "internalType": "bytes[]",
          "name": "data",
          "type": "bytes[]"
        },
        {
          "internalType": "bool",
          "name": "reverseRecord",
          "type": "bool"
        },
        {
          "internalType": "uint32",
          "name": "fuses",
          "type": "uint32"
        },
        {
          "internalType": "uint64",
          "name": "wrapperExpiry",
          "type": "uint64"
        }
      ],
      "name": "register",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        },
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        }
      ],
      "name": "renew",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        },
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        },
        {
          "internalType": "uint32",
          "name": "fuses",
          "type": "uint32"
        },
        {
          "internalType": "uint64",
          "name": "wrapperExpiry",
          "type": "uint64"
        }
      ],
      "name": "renewWithFuses",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        },
        {
          "internalType": "uint256",
          "name": "duration",
          "type": "uint256"
        }
      ],
      "name": "rentPrice",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "base",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "premium",
              "type": "uint256"
            }
          ],
          "internalType": "struct IPriceOracle.Price",
          "name": "price",
          "type": "tuple"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "reverseRegistrar",
      "outputs": [
        {
          "internalType": "contract ReverseRegistrar",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes4",
          "name": "interfaceID",
          "type": "bytes4"
        }
      ],
      "name": "supportsInterface",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        }
      ],
      "name": "valid",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "pure",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "withdraw",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0x70ee666425d9c7d10a68c03c9aae371af027ecd3b9503a3ac39bd9efc248797d",
  "receipt": {
    "to": null,
    "from": "0xa303ddC620aa7d1390BACcc8A495508B183fab59",
    "contractAddress": "0xa5627AB7Ae47063B533622C34FEBDb52d3281dF8",
    "transactionIndex": 15,
    "gasUsed": "2127185",
    "logsBloom": "0x00000000000000200000000000000000000040000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001000000000000000000000000010000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0xc0f9afeb4508c3173f8c19acbcf7f69f3bfdb856cf3f726f94e5a1b012f05526",
    "transactionHash": "0x70ee666425d9c7d10a68c03c9aae371af027ecd3b9503a3ac39bd9efc248797d",
    "logs": [
      {
        "transactionIndex": 15,
        "blockNumber": 13068663,
        "transactionHash": "0x70ee666425d9c7d10a68c03c9aae371af027ecd3b9503a3ac39bd9efc248797d",
        "address": "0xa5627AB7Ae47063B533622C34FEBDb52d3281dF8",
        "topics": [
          "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x000000000000000000000000a303ddc620aa7d1390baccc8a495508b183fab59"
        ],
        "data": "0x",
        "logIndex": 38,
        "blockHash": "0xc0f9afeb4508c3173f8c19acbcf7f69f3bfdb856cf3f726f94e5a1b012f05526"
      }
    ],
    "blockNumber": 13068663,
    "cumulativeGasUsed": "4240769",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85",
    "0x0e765d28FABf9E219770CAb07D64967451026bD7",
    60,
    86400,
    "0x806246b52f8cB61655d3038c58D2f63Aa55d4edE",
    "0xF82155e2a43Be0871821E9654Fc8Ae894FB8307C"
  ],
  "numDeployments": 2,
  "solcInputHash": "e0f6f00faee6ee60a1220d91a962cdaa",
  "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract BaseRegistrarImplementation\",\"name\":\"_base\",\"type\":\"address\"},{\"internalType\":\"contract IPriceOracle\",\"name\":\"_prices\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_minCommitmentAge\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxCommitmentAge\",\"type\":\"uint256\"},{\"internalType\":\"contract ReverseRegistrar\",\"name\":\"_reverseRegistrar\",\"type\":\"address\"},{\"internalType\":\"contract INameWrapper\",\"name\":\"_nameWrapper\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"CommitmentTooNew\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"CommitmentTooOld\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"DurationTooShort\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCommitmentAgeTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCommitmentAgeTooLow\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NameNotAvailable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverRequiredWhenDataSupplied\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"Unauthorised\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"UnexpiredCommitmentExists\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"baseCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"premium\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expires\",\"type\":\"uint256\"}],\"name\":\"NameRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"label\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"cost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expires\",\"type\":\"uint256\"}],\"name\":\"NameRenewed\",\"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\"},{\"inputs\":[],\"name\":\"MIN_REGISTRATION_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"available\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"commit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"commitments\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"bool\",\"name\":\"reverseRecord\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"fuses\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"wrapperExpiry\",\"type\":\"uint64\"}],\"name\":\"makeCommitment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxCommitmentAge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minCommitmentAge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nameWrapper\",\"outputs\":[{\"internalType\":\"contract INameWrapper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"prices\",\"outputs\":[{\"internalType\":\"contract IPriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"bool\",\"name\":\"reverseRecord\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"fuses\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"wrapperExpiry\",\"type\":\"uint64\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"renew\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"fuses\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"wrapperExpiry\",\"type\":\"uint64\"}],\"name\":\"renewWithFuses\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"rentPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"base\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"premium\",\"type\":\"uint256\"}],\"internalType\":\"struct IPriceOracle.Price\",\"name\":\"price\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reverseRegistrar\",\"outputs\":[{\"internalType\":\"contract ReverseRegistrar\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"valid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"A registrar controller for registering and renewing names at fixed cost.\",\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"recoverFunds(address,address,uint256)\":{\"details\":\"The contract is Ownable and only the owner can call the recover function.\",\"params\":{\"_amount\":\"The amount of tokens to recover.\",\"_to\":\"The address to send the tokens to.\",\"_token\":\"The address of the ERC20 token to recover\"}},\"renounceOwnership()\":{\"details\":\"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.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"recoverFunds(address,address,uint256)\":{\"notice\":\"Recover ERC20 tokens sent to the contract by mistake.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ethregistrar/ETHRegistrarController.sol\":\"ETHRegistrarController\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n    address private _owner;\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the deployer as the initial owner.\\n     */\\n    constructor() {\\n        _transferOwnership(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n        _;\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby removing any functionality that is only available to the owner.\\n     */\\n    function renounceOwnership() public virtual onlyOwner {\\n        _transferOwnership(address(0));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual onlyOwner {\\n        require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n        _transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n}\\n\",\"keccak256\":\"0x24e0364e503a9bbde94c715d26573a76f14cd2a202d45f96f52134ab806b67b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\\n *\\n * _Available since v3.1._\\n */\\ninterface IERC1155 is IERC165 {\\n    /**\\n     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\\n     */\\n    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\\n\\n    /**\\n     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\\n     * transfers.\\n     */\\n    event TransferBatch(\\n        address indexed operator,\\n        address indexed from,\\n        address indexed to,\\n        uint256[] ids,\\n        uint256[] values\\n    );\\n\\n    /**\\n     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\\n     * `approved`.\\n     */\\n    event ApprovalForAll(address indexed account, address indexed operator, bool approved);\\n\\n    /**\\n     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\\n     *\\n     * If an {URI} event was emitted for `id`, the standard\\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\\n     * returned by {IERC1155MetadataURI-uri}.\\n     */\\n    event URI(string value, uint256 indexed id);\\n\\n    /**\\n     * @dev Returns the amount of tokens of token type `id` owned by `account`.\\n     *\\n     * Requirements:\\n     *\\n     * - `account` cannot be the zero address.\\n     */\\n    function balanceOf(address account, uint256 id) external view returns (uint256);\\n\\n    /**\\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\\n     *\\n     * Requirements:\\n     *\\n     * - `accounts` and `ids` must have the same length.\\n     */\\n    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\\n        external\\n        view\\n        returns (uint256[] memory);\\n\\n    /**\\n     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\\n     *\\n     * Emits an {ApprovalForAll} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `operator` cannot be the caller.\\n     */\\n    function setApprovalForAll(address operator, bool approved) external;\\n\\n    /**\\n     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\\n     *\\n     * See {setApprovalForAll}.\\n     */\\n    function isApprovedForAll(address account, address operator) external view returns (bool);\\n\\n    /**\\n     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\\n     *\\n     * Emits a {TransferSingle} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `to` cannot be the zero address.\\n     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\\n     * - `from` must have a balance of tokens of type `id` of at least `amount`.\\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\\n     * acceptance magic value.\\n     */\\n    function safeTransferFrom(\\n        address from,\\n        address to,\\n        uint256 id,\\n        uint256 amount,\\n        bytes calldata data\\n    ) external;\\n\\n    /**\\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\\n     *\\n     * Emits a {TransferBatch} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `ids` and `amounts` must have the same length.\\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\\n     * acceptance magic value.\\n     */\\n    function safeBatchTransferFrom(\\n        address from,\\n        address to,\\n        uint256[] calldata ids,\\n        uint256[] calldata amounts,\\n        bytes calldata data\\n    ) external;\\n}\\n\",\"keccak256\":\"0x8e93de94c9062ebc94fb7e2e3929b0781ac6a2b7772e2f7a59045861c93e5be9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) external returns (bool);\\n\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC721.sol\\\";\\nimport \\\"./IERC721Receiver.sol\\\";\\nimport \\\"./extensions/IERC721Metadata.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"../../utils/Strings.sol\\\";\\nimport \\\"../../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\\n    using Address for address;\\n    using Strings for uint256;\\n\\n    // Token name\\n    string private _name;\\n\\n    // Token symbol\\n    string private _symbol;\\n\\n    // Mapping from token ID to owner address\\n    mapping(uint256 => address) private _owners;\\n\\n    // Mapping owner address to token count\\n    mapping(address => uint256) private _balances;\\n\\n    // Mapping from token ID to approved address\\n    mapping(uint256 => address) private _tokenApprovals;\\n\\n    // Mapping from owner to operator approvals\\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\\n\\n    /**\\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n     */\\n    constructor(string memory name_, string memory symbol_) {\\n        _name = name_;\\n        _symbol = symbol_;\\n    }\\n\\n    /**\\n     * @dev See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\\n        return\\n            interfaceId == type(IERC721).interfaceId ||\\n            interfaceId == type(IERC721Metadata).interfaceId ||\\n            super.supportsInterface(interfaceId);\\n    }\\n\\n    /**\\n     * @dev See {IERC721-balanceOf}.\\n     */\\n    function balanceOf(address owner) public view virtual override returns (uint256) {\\n        require(owner != address(0), \\\"ERC721: balance query for the zero address\\\");\\n        return _balances[owner];\\n    }\\n\\n    /**\\n     * @dev See {IERC721-ownerOf}.\\n     */\\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n        address owner = _owners[tokenId];\\n        require(owner != address(0), \\\"ERC721: owner query for nonexistent token\\\");\\n        return owner;\\n    }\\n\\n    /**\\n     * @dev See {IERC721Metadata-name}.\\n     */\\n    function name() public view virtual override returns (string memory) {\\n        return _name;\\n    }\\n\\n    /**\\n     * @dev See {IERC721Metadata-symbol}.\\n     */\\n    function symbol() public view virtual override returns (string memory) {\\n        return _symbol;\\n    }\\n\\n    /**\\n     * @dev See {IERC721Metadata-tokenURI}.\\n     */\\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n        require(_exists(tokenId), \\\"ERC721Metadata: URI query for nonexistent token\\\");\\n\\n        string memory baseURI = _baseURI();\\n        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n    }\\n\\n    /**\\n     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n     * by default, can be overriden in child contracts.\\n     */\\n    function _baseURI() internal view virtual returns (string memory) {\\n        return \\\"\\\";\\n    }\\n\\n    /**\\n     * @dev See {IERC721-approve}.\\n     */\\n    function approve(address to, uint256 tokenId) public virtual override {\\n        address owner = ERC721.ownerOf(tokenId);\\n        require(to != owner, \\\"ERC721: approval to current owner\\\");\\n\\n        require(\\n            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\\n            \\\"ERC721: approve caller is not owner nor approved for all\\\"\\n        );\\n\\n        _approve(to, tokenId);\\n    }\\n\\n    /**\\n     * @dev See {IERC721-getApproved}.\\n     */\\n    function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n        require(_exists(tokenId), \\\"ERC721: approved query for nonexistent token\\\");\\n\\n        return _tokenApprovals[tokenId];\\n    }\\n\\n    /**\\n     * @dev See {IERC721-setApprovalForAll}.\\n     */\\n    function setApprovalForAll(address operator, bool approved) public virtual override {\\n        _setApprovalForAll(_msgSender(), operator, approved);\\n    }\\n\\n    /**\\n     * @dev See {IERC721-isApprovedForAll}.\\n     */\\n    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n        return _operatorApprovals[owner][operator];\\n    }\\n\\n    /**\\n     * @dev See {IERC721-transferFrom}.\\n     */\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 tokenId\\n    ) public virtual override {\\n        //solhint-disable-next-line max-line-length\\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\n\\n        _transfer(from, to, tokenId);\\n    }\\n\\n    /**\\n     * @dev See {IERC721-safeTransferFrom}.\\n     */\\n    function safeTransferFrom(\\n        address from,\\n        address to,\\n        uint256 tokenId\\n    ) public virtual override {\\n        safeTransferFrom(from, to, tokenId, \\\"\\\");\\n    }\\n\\n    /**\\n     * @dev See {IERC721-safeTransferFrom}.\\n     */\\n    function safeTransferFrom(\\n        address from,\\n        address to,\\n        uint256 tokenId,\\n        bytes memory _data\\n    ) public virtual override {\\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: transfer caller is not owner nor approved\\\");\\n        _safeTransfer(from, to, tokenId, _data);\\n    }\\n\\n    /**\\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n     *\\n     * `_data` is additional data, it has no specified format and it is sent in call to `to`.\\n     *\\n     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must exist and be owned by `from`.\\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _safeTransfer(\\n        address from,\\n        address to,\\n        uint256 tokenId,\\n        bytes memory _data\\n    ) internal virtual {\\n        _transfer(from, to, tokenId);\\n        require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n    }\\n\\n    /**\\n     * @dev Returns whether `tokenId` exists.\\n     *\\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\\n     *\\n     * Tokens start existing when they are minted (`_mint`),\\n     * and stop existing when they are burned (`_burn`).\\n     */\\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\\n        return _owners[tokenId] != address(0);\\n    }\\n\\n    /**\\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must exist.\\n     */\\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n        require(_exists(tokenId), \\\"ERC721: operator query for nonexistent token\\\");\\n        address owner = ERC721.ownerOf(tokenId);\\n        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\\n    }\\n\\n    /**\\n     * @dev Safely mints `tokenId` and transfers it to `to`.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must not exist.\\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _safeMint(address to, uint256 tokenId) internal virtual {\\n        _safeMint(to, tokenId, \\\"\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n     */\\n    function _safeMint(\\n        address to,\\n        uint256 tokenId,\\n        bytes memory _data\\n    ) internal virtual {\\n        _mint(to, tokenId);\\n        require(\\n            _checkOnERC721Received(address(0), to, tokenId, _data),\\n            \\\"ERC721: transfer to non ERC721Receiver implementer\\\"\\n        );\\n    }\\n\\n    /**\\n     * @dev Mints `tokenId` and transfers it to `to`.\\n     *\\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must not exist.\\n     * - `to` cannot be the zero address.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _mint(address to, uint256 tokenId) internal virtual {\\n        require(to != address(0), \\\"ERC721: mint to the zero address\\\");\\n        require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n        _beforeTokenTransfer(address(0), to, tokenId);\\n\\n        _balances[to] += 1;\\n        _owners[tokenId] = to;\\n\\n        emit Transfer(address(0), to, tokenId);\\n\\n        _afterTokenTransfer(address(0), to, tokenId);\\n    }\\n\\n    /**\\n     * @dev Destroys `tokenId`.\\n     * The approval is cleared when the token is burned.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must exist.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _burn(uint256 tokenId) internal virtual {\\n        address owner = ERC721.ownerOf(tokenId);\\n\\n        _beforeTokenTransfer(owner, address(0), tokenId);\\n\\n        // Clear approvals\\n        _approve(address(0), tokenId);\\n\\n        _balances[owner] -= 1;\\n        delete _owners[tokenId];\\n\\n        emit Transfer(owner, address(0), tokenId);\\n\\n        _afterTokenTransfer(owner, address(0), tokenId);\\n    }\\n\\n    /**\\n     * @dev Transfers `tokenId` from `from` to `to`.\\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n     *\\n     * Requirements:\\n     *\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must be owned by `from`.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function _transfer(\\n        address from,\\n        address to,\\n        uint256 tokenId\\n    ) internal virtual {\\n        require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n        require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n        _beforeTokenTransfer(from, to, tokenId);\\n\\n        // Clear approvals from the previous owner\\n        _approve(address(0), tokenId);\\n\\n        _balances[from] -= 1;\\n        _balances[to] += 1;\\n        _owners[tokenId] = to;\\n\\n        emit Transfer(from, to, tokenId);\\n\\n        _afterTokenTransfer(from, to, tokenId);\\n    }\\n\\n    /**\\n     * @dev Approve `to` to operate on `tokenId`\\n     *\\n     * Emits a {Approval} event.\\n     */\\n    function _approve(address to, uint256 tokenId) internal virtual {\\n        _tokenApprovals[tokenId] = to;\\n        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n    }\\n\\n    /**\\n     * @dev Approve `operator` to operate on all of `owner` tokens\\n     *\\n     * Emits a {ApprovalForAll} event.\\n     */\\n    function _setApprovalForAll(\\n        address owner,\\n        address operator,\\n        bool approved\\n    ) internal virtual {\\n        require(owner != operator, \\\"ERC721: approve to caller\\\");\\n        _operatorApprovals[owner][operator] = approved;\\n        emit ApprovalForAll(owner, operator, approved);\\n    }\\n\\n    /**\\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n     * The call is not executed if the target address is not a contract.\\n     *\\n     * @param from address representing the previous owner of the given token ID\\n     * @param to target address that will receive the tokens\\n     * @param tokenId uint256 ID of the token to be transferred\\n     * @param _data bytes optional data to send along with the call\\n     * @return bool whether the call correctly returned the expected magic value\\n     */\\n    function _checkOnERC721Received(\\n        address from,\\n        address to,\\n        uint256 tokenId,\\n        bytes memory _data\\n    ) private returns (bool) {\\n        if (to.isContract()) {\\n            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {\\n                return retval == IERC721Receiver.onERC721Received.selector;\\n            } catch (bytes memory reason) {\\n                if (reason.length == 0) {\\n                    revert(\\\"ERC721: transfer to non ERC721Receiver implementer\\\");\\n                } else {\\n                    assembly {\\n                        revert(add(32, reason), mload(reason))\\n                    }\\n                }\\n            }\\n        } else {\\n            return true;\\n        }\\n    }\\n\\n    /**\\n     * @dev Hook that is called before any token transfer. This includes minting\\n     * and burning.\\n     *\\n     * Calling conditions:\\n     *\\n     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\\n     * transferred to `to`.\\n     * - When `from` is zero, `tokenId` will be minted for `to`.\\n     * - When `to` is zero, ``from``'s `tokenId` will be burned.\\n     * - `from` and `to` are never both zero.\\n     *\\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n     */\\n    function _beforeTokenTransfer(\\n        address from,\\n        address to,\\n        uint256 tokenId\\n    ) internal virtual {}\\n\\n    /**\\n     * @dev Hook that is called after any transfer of tokens. This includes\\n     * minting and burning.\\n     *\\n     * Calling conditions:\\n     *\\n     * - when `from` and `to` are both non-zero.\\n     * - `from` and `to` are never both zero.\\n     *\\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n     */\\n    function _afterTokenTransfer(\\n        address from,\\n        address to,\\n        uint256 tokenId\\n    ) internal virtual {}\\n}\\n\",\"keccak256\":\"0x11b84bb56dc112a6590bfe3e0efa118aa1b5891132342200d04c4ef544cb93de\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n    /**\\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n    /**\\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n     */\\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n    /**\\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n     */\\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n    /**\\n     * @dev Returns the number of tokens in ``owner``'s account.\\n     */\\n    function balanceOf(address owner) external view returns (uint256 balance);\\n\\n    /**\\n     * @dev Returns the owner of the `tokenId` token.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must exist.\\n     */\\n    function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n    /**\\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must exist and be owned by `from`.\\n     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function safeTransferFrom(\\n        address from,\\n        address to,\\n        uint256 tokenId\\n    ) external;\\n\\n    /**\\n     * @dev Transfers `tokenId` token from `from` to `to`.\\n     *\\n     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must be owned by `from`.\\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 tokenId\\n    ) external;\\n\\n    /**\\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n     * The approval is cleared when the token is transferred.\\n     *\\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n     *\\n     * Requirements:\\n     *\\n     * - The caller must own the token or be an approved operator.\\n     * - `tokenId` must exist.\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address to, uint256 tokenId) external;\\n\\n    /**\\n     * @dev Returns the account approved for `tokenId` token.\\n     *\\n     * Requirements:\\n     *\\n     * - `tokenId` must exist.\\n     */\\n    function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n    /**\\n     * @dev Approve or remove `operator` as an operator for the caller.\\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n     *\\n     * Requirements:\\n     *\\n     * - The `operator` cannot be the caller.\\n     *\\n     * Emits an {ApprovalForAll} event.\\n     */\\n    function setApprovalForAll(address operator, bool _approved) external;\\n\\n    /**\\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n     *\\n     * See {setApprovalForAll}\\n     */\\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\\n\\n    /**\\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `tokenId` token must exist and be owned by `from`.\\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function safeTransferFrom(\\n        address from,\\n        address to,\\n        uint256 tokenId,\\n        bytes calldata data\\n    ) external;\\n}\\n\",\"keccak256\":\"0x516a22876c1fab47f49b1bc22b4614491cd05338af8bd2e7b382da090a079990\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n    /**\\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n     * by `operator` from `from`, this function is called.\\n     *\\n     * It must return its Solidity selector to confirm the token transfer.\\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n     *\\n     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\\n     */\\n    function onERC721Received(\\n        address operator,\\n        address from,\\n        uint256 tokenId,\\n        bytes calldata data\\n    ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xd5fa74b4fb323776fa4a8158800fec9d5ac0fec0d6dd046dd93798632ada265f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n    /**\\n     * @dev Returns the token collection name.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the token collection symbol.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n     */\\n    function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     * ====\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n     *\\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n     * constructor.\\n     * ====\\n     */\\n    function isContract(address account) internal view returns (bool) {\\n        // This method relies on extcodesize/address.code.length, which returns 0\\n        // for contracts in construction, since the code is only stored at the end\\n        // of the constructor execution.\\n\\n        return account.code.length > 0;\\n    }\\n\\n    /**\\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n     * `recipient`, forwarding all available gas and reverting on errors.\\n     *\\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n     * imposed by `transfer`, making them unable to receive funds via\\n     * `transfer`. {sendValue} removes this limitation.\\n     *\\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n     *\\n     * IMPORTANT: because control is transferred to `recipient`, care must be\\n     * taken to not create reentrancy vulnerabilities. Consider using\\n     * {ReentrancyGuard} or the\\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n     */\\n    function sendValue(address payable recipient, uint256 amount) internal {\\n        require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n        (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n        require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n    }\\n\\n    /**\\n     * @dev Performs a Solidity function call using a low level `call`. A\\n     * plain `call` is an unsafe replacement for a function call: use this\\n     * function instead.\\n     *\\n     * If `target` reverts with a revert reason, it is bubbled up by this\\n     * function (like regular Solidity function calls).\\n     *\\n     * Returns the raw returned data. To convert to the expected return value,\\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n     *\\n     * Requirements:\\n     *\\n     * - `target` must be a contract.\\n     * - calling `target` with `data` must not revert.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n     * `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but also transferring `value` wei to `target`.\\n     *\\n     * Requirements:\\n     *\\n     * - the calling contract must have an ETH balance of at least `value`.\\n     * - the called Solidity function must be `payable`.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n        require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason using the provided one.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function verifyCallResult(\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal pure returns (bytes memory) {\\n        if (success) {\\n            return returndata;\\n        } else {\\n            // Look for revert reason and bubble it up if present\\n            if (returndata.length > 0) {\\n                // The easiest way to bubble the revert reason is using memory via assembly\\n\\n                assembly {\\n                    let returndata_size := mload(returndata)\\n                    revert(add(32, returndata), returndata_size)\\n                }\\n            } else {\\n                revert(errorMessage);\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n    bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n     */\\n    function toString(uint256 value) internal pure returns (string memory) {\\n        // Inspired by OraclizeAPI's implementation - MIT licence\\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n        if (value == 0) {\\n            return \\\"0\\\";\\n        }\\n        uint256 temp = value;\\n        uint256 digits;\\n        while (temp != 0) {\\n            digits++;\\n            temp /= 10;\\n        }\\n        bytes memory buffer = new bytes(digits);\\n        while (value != 0) {\\n            digits -= 1;\\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n            value /= 10;\\n        }\\n        return string(buffer);\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n     */\\n    function toHexString(uint256 value) internal pure returns (string memory) {\\n        if (value == 0) {\\n            return \\\"0x00\\\";\\n        }\\n        uint256 temp = value;\\n        uint256 length = 0;\\n        while (temp != 0) {\\n            length++;\\n            temp >>= 8;\\n        }\\n        return toHexString(value, length);\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n     */\\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n        bytes memory buffer = new bytes(2 * length + 2);\\n        buffer[0] = \\\"0\\\";\\n        buffer[1] = \\\"x\\\";\\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n            value >>= 4;\\n        }\\n        require(value == 0, \\\"Strings: hex length insufficient\\\");\\n        return string(buffer);\\n    }\\n}\\n\",\"keccak256\":\"0x32c202bd28995dd20c4347b7c6467a6d3241c74c8ad3edcbb610cd9205916c45\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n    /**\\n     * @dev See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n        return interfaceId == type(IERC165).interfaceId;\\n    }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n    /**\\n     * @dev Returns true if this contract implements the interface defined by\\n     * `interfaceId`. See the corresponding\\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n     * to learn more about how these ids are created.\\n     *\\n     * This function call must use less than 30 000 gas.\\n     */\\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/ethregistrar/BaseRegistrarImplementation.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\nimport \\\"../registry/ENS.sol\\\";\\nimport \\\"./IBaseRegistrar.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\ncontract BaseRegistrarImplementation is ERC721, IBaseRegistrar, Ownable {\\n    // A map of expiry times\\n    mapping(uint256 => uint256) expiries;\\n    // The ENS registry\\n    ENS public ens;\\n    // The namehash of the TLD this registrar owns (eg, .eth)\\n    bytes32 public baseNode;\\n    // A map of addresses that are authorised to register and renew names.\\n    mapping(address => bool) public controllers;\\n    uint256 public constant GRACE_PERIOD = 90 days;\\n    bytes4 private constant INTERFACE_META_ID =\\n        bytes4(keccak256(\\\"supportsInterface(bytes4)\\\"));\\n    bytes4 private constant ERC721_ID =\\n        bytes4(\\n            keccak256(\\\"balanceOf(address)\\\") ^\\n                keccak256(\\\"ownerOf(uint256)\\\") ^\\n                keccak256(\\\"approve(address,uint256)\\\") ^\\n                keccak256(\\\"getApproved(uint256)\\\") ^\\n                keccak256(\\\"setApprovalForAll(address,bool)\\\") ^\\n                keccak256(\\\"isApprovedForAll(address,address)\\\") ^\\n                keccak256(\\\"transferFrom(address,address,uint256)\\\") ^\\n                keccak256(\\\"safeTransferFrom(address,address,uint256)\\\") ^\\n                keccak256(\\\"safeTransferFrom(address,address,uint256,bytes)\\\")\\n        );\\n    bytes4 private constant RECLAIM_ID =\\n        bytes4(keccak256(\\\"reclaim(uint256,address)\\\"));\\n\\n    /**\\n     * v2.1.3 version of _isApprovedOrOwner which calls ownerOf(tokenId) and takes grace period into consideration instead of ERC721.ownerOf(tokenId);\\n     * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.1.3/contracts/token/ERC721/ERC721.sol#L187\\n     * @dev Returns whether the given spender can transfer a given token ID\\n     * @param spender address of the spender to query\\n     * @param tokenId uint256 ID of the token to be transferred\\n     * @return bool whether the msg.sender is approved for the given token ID,\\n     *    is an operator of the owner, or is the owner of the token\\n     */\\n    function _isApprovedOrOwner(address spender, uint256 tokenId)\\n        internal\\n        view\\n        override\\n        returns (bool)\\n    {\\n        address owner = ownerOf(tokenId);\\n        return (spender == owner ||\\n            getApproved(tokenId) == spender ||\\n            isApprovedForAll(owner, spender));\\n    }\\n\\n    constructor(ENS _ens, bytes32 _baseNode) ERC721(\\\"\\\", \\\"\\\") {\\n        ens = _ens;\\n        baseNode = _baseNode;\\n    }\\n\\n    modifier live() {\\n        require(ens.owner(baseNode) == address(this));\\n        _;\\n    }\\n\\n    modifier onlyController() {\\n        require(controllers[msg.sender]);\\n        _;\\n    }\\n\\n    /**\\n     * @dev Gets the owner of the specified token ID. Names become unowned\\n     *      when their registration expires.\\n     * @param tokenId uint256 ID of the token to query the owner of\\n     * @return address currently marked as the owner of the given token ID\\n     */\\n    function ownerOf(uint256 tokenId)\\n        public\\n        view\\n        override(IERC721, ERC721)\\n        returns (address)\\n    {\\n        require(expiries[tokenId] > block.timestamp);\\n        return super.ownerOf(tokenId);\\n    }\\n\\n    // Authorises a controller, who can register and renew domains.\\n    function addController(address controller) external override onlyOwner {\\n        controllers[controller] = true;\\n        emit ControllerAdded(controller);\\n    }\\n\\n    // Revoke controller permission for an address.\\n    function removeController(address controller) external override onlyOwner {\\n        controllers[controller] = false;\\n        emit ControllerRemoved(controller);\\n    }\\n\\n    // Set the resolver for the TLD this registrar manages.\\n    function setResolver(address resolver) external override onlyOwner {\\n        ens.setResolver(baseNode, resolver);\\n    }\\n\\n    // Returns the expiration timestamp of the specified id.\\n    function nameExpires(uint256 id) external view override returns (uint256) {\\n        return expiries[id];\\n    }\\n\\n    // Returns true iff the specified name is available for registration.\\n    function available(uint256 id) public view override returns (bool) {\\n        // Not available if it's registered here or in its grace period.\\n        return expiries[id] + GRACE_PERIOD < block.timestamp;\\n    }\\n\\n    /**\\n     * @dev Register a name.\\n     * @param id The token ID (keccak256 of the label).\\n     * @param owner The address that should own the registration.\\n     * @param duration Duration in seconds for the registration.\\n     */\\n    function register(\\n        uint256 id,\\n        address owner,\\n        uint256 duration\\n    ) external override returns (uint256) {\\n        return _register(id, owner, duration, true);\\n    }\\n\\n    /**\\n     * @dev Register a name, without modifying the registry.\\n     * @param id The token ID (keccak256 of the label).\\n     * @param owner The address that should own the registration.\\n     * @param duration Duration in seconds for the registration.\\n     */\\n    function registerOnly(\\n        uint256 id,\\n        address owner,\\n        uint256 duration\\n    ) external returns (uint256) {\\n        return _register(id, owner, duration, false);\\n    }\\n\\n    function _register(\\n        uint256 id,\\n        address owner,\\n        uint256 duration,\\n        bool updateRegistry\\n    ) internal live onlyController returns (uint256) {\\n        require(available(id));\\n        require(\\n            block.timestamp + duration + GRACE_PERIOD >\\n                block.timestamp + GRACE_PERIOD\\n        ); // Prevent future overflow\\n\\n        expiries[id] = block.timestamp + duration;\\n        if (_exists(id)) {\\n            // Name was previously owned, and expired\\n            _burn(id);\\n        }\\n        _mint(owner, id);\\n        if (updateRegistry) {\\n            ens.setSubnodeOwner(baseNode, bytes32(id), owner);\\n        }\\n\\n        emit NameRegistered(id, owner, block.timestamp + duration);\\n\\n        return block.timestamp + duration;\\n    }\\n\\n    function renew(uint256 id, uint256 duration)\\n        external\\n        override\\n        live\\n        onlyController\\n        returns (uint256)\\n    {\\n        require(expiries[id] + GRACE_PERIOD >= block.timestamp); // Name must be registered here or in grace period\\n        require(\\n            expiries[id] + duration + GRACE_PERIOD > duration + GRACE_PERIOD\\n        ); // Prevent future overflow\\n\\n        expiries[id] += duration;\\n        emit NameRenewed(id, expiries[id]);\\n        return expiries[id];\\n    }\\n\\n    /**\\n     * @dev Reclaim ownership of a name in ENS, if you own it in the registrar.\\n     */\\n    function reclaim(uint256 id, address owner) external override live {\\n        require(_isApprovedOrOwner(msg.sender, id));\\n        ens.setSubnodeOwner(baseNode, bytes32(id), owner);\\n    }\\n\\n    function supportsInterface(bytes4 interfaceID)\\n        public\\n        view\\n        override(ERC721, IERC165)\\n        returns (bool)\\n    {\\n        return\\n            interfaceID == INTERFACE_META_ID ||\\n            interfaceID == ERC721_ID ||\\n            interfaceID == RECLAIM_ID;\\n    }\\n}\\n\",\"keccak256\":\"0xb757a151137d4b1b877773226797c8f95a4320cd3d68c7c2cfa588b22f5438ed\"},\"contracts/ethregistrar/ETHRegistrarController.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nimport {BaseRegistrarImplementation} from \\\"./BaseRegistrarImplementation.sol\\\";\\nimport {StringUtils} from \\\"./StringUtils.sol\\\";\\nimport {Resolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {ReverseRegistrar} from \\\"../registry/ReverseRegistrar.sol\\\";\\nimport {IETHRegistrarController, IPriceOracle} from \\\"./IETHRegistrarController.sol\\\";\\n\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {INameWrapper} from \\\"../wrapper/INameWrapper.sol\\\";\\nimport {ERC20Recoverable} from \\\"../utils/ERC20Recoverable.sol\\\";\\n\\nerror CommitmentTooNew(bytes32 commitment);\\nerror CommitmentTooOld(bytes32 commitment);\\nerror NameNotAvailable(string name);\\nerror DurationTooShort(uint256 duration);\\nerror ResolverRequiredWhenDataSupplied();\\nerror UnexpiredCommitmentExists(bytes32 commitment);\\nerror InsufficientValue();\\nerror Unauthorised(bytes32 node);\\nerror MaxCommitmentAgeTooLow();\\nerror MaxCommitmentAgeTooHigh();\\n\\n/**\\n * @dev A registrar controller for registering and renewing names at fixed cost.\\n */\\ncontract ETHRegistrarController is\\n    Ownable,\\n    IETHRegistrarController,\\n    IERC165,\\n    ERC20Recoverable\\n{\\n    using StringUtils for *;\\n    using Address for address;\\n\\n    uint256 public constant MIN_REGISTRATION_DURATION = 28 days;\\n    bytes32 private constant ETH_NODE =\\n        0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;\\n    uint64 private constant MAX_EXPIRY = type(uint64).max;\\n    BaseRegistrarImplementation immutable base;\\n    IPriceOracle public immutable prices;\\n    uint256 public immutable minCommitmentAge;\\n    uint256 public immutable maxCommitmentAge;\\n    ReverseRegistrar public immutable reverseRegistrar;\\n    INameWrapper public immutable nameWrapper;\\n\\n    mapping(bytes32 => uint256) public commitments;\\n\\n    event NameRegistered(\\n        string name,\\n        bytes32 indexed label,\\n        address indexed owner,\\n        uint256 baseCost,\\n        uint256 premium,\\n        uint256 expires\\n    );\\n    event NameRenewed(\\n        string name,\\n        bytes32 indexed label,\\n        uint256 cost,\\n        uint256 expires\\n    );\\n\\n    constructor(\\n        BaseRegistrarImplementation _base,\\n        IPriceOracle _prices,\\n        uint256 _minCommitmentAge,\\n        uint256 _maxCommitmentAge,\\n        ReverseRegistrar _reverseRegistrar,\\n        INameWrapper _nameWrapper\\n    ) {\\n        if (_maxCommitmentAge <= _minCommitmentAge) {\\n            revert MaxCommitmentAgeTooLow();\\n        }\\n\\n        if (_maxCommitmentAge > block.timestamp) {\\n            revert MaxCommitmentAgeTooHigh();\\n        }\\n\\n        base = _base;\\n        prices = _prices;\\n        minCommitmentAge = _minCommitmentAge;\\n        maxCommitmentAge = _maxCommitmentAge;\\n        reverseRegistrar = _reverseRegistrar;\\n        nameWrapper = _nameWrapper;\\n    }\\n\\n    function rentPrice(string memory name, uint256 duration)\\n        public\\n        view\\n        override\\n        returns (IPriceOracle.Price memory price)\\n    {\\n        bytes32 label = keccak256(bytes(name));\\n        price = prices.price(name, base.nameExpires(uint256(label)), duration);\\n    }\\n\\n    function valid(string memory name) public pure returns (bool) {\\n        return name.strlen() >= 3;\\n    }\\n\\n    function available(string memory name) public view override returns (bool) {\\n        bytes32 label = keccak256(bytes(name));\\n        return valid(name) && base.available(uint256(label));\\n    }\\n\\n    function makeCommitment(\\n        string memory name,\\n        address owner,\\n        uint256 duration,\\n        bytes32 secret,\\n        address resolver,\\n        bytes[] calldata data,\\n        bool reverseRecord,\\n        uint32 fuses,\\n        uint64 wrapperExpiry\\n    ) public pure override returns (bytes32) {\\n        bytes32 label = keccak256(bytes(name));\\n        if (data.length > 0 && resolver == address(0)) {\\n            revert ResolverRequiredWhenDataSupplied();\\n        }\\n        return\\n            keccak256(\\n                abi.encode(\\n                    label,\\n                    owner,\\n                    duration,\\n                    resolver,\\n                    data,\\n                    secret,\\n                    reverseRecord,\\n                    fuses,\\n                    wrapperExpiry\\n                )\\n            );\\n    }\\n\\n    function commit(bytes32 commitment) public override {\\n        if (commitments[commitment] + maxCommitmentAge >= block.timestamp) {\\n            revert UnexpiredCommitmentExists(commitment);\\n        }\\n        commitments[commitment] = block.timestamp;\\n    }\\n\\n    function register(\\n        string calldata name,\\n        address owner,\\n        uint256 duration,\\n        bytes32 secret,\\n        address resolver,\\n        bytes[] calldata data,\\n        bool reverseRecord,\\n        uint32 fuses,\\n        uint64 wrapperExpiry\\n    ) public payable override {\\n        IPriceOracle.Price memory price = rentPrice(name, duration);\\n        if (msg.value < price.base + price.premium) {\\n            revert InsufficientValue();\\n        }\\n\\n        _consumeCommitment(\\n            name,\\n            duration,\\n            makeCommitment(\\n                name,\\n                owner,\\n                duration,\\n                secret,\\n                resolver,\\n                data,\\n                reverseRecord,\\n                fuses,\\n                wrapperExpiry\\n            )\\n        );\\n\\n        uint256 expires = nameWrapper.registerAndWrapETH2LD(\\n            name,\\n            owner,\\n            duration,\\n            resolver,\\n            fuses,\\n            wrapperExpiry\\n        );\\n\\n        if (data.length > 0) {\\n            _setRecords(resolver, keccak256(bytes(name)), data);\\n        }\\n\\n        if (reverseRecord) {\\n            _setReverseRecord(name, resolver, msg.sender);\\n        }\\n\\n        emit NameRegistered(\\n            name,\\n            keccak256(bytes(name)),\\n            owner,\\n            price.base,\\n            price.premium,\\n            expires\\n        );\\n\\n        if (msg.value > (price.base + price.premium)) {\\n            payable(msg.sender).transfer(\\n                msg.value - (price.base + price.premium)\\n            );\\n        }\\n    }\\n\\n    function renew(string calldata name, uint256 duration)\\n        external\\n        payable\\n        override\\n    {\\n        _renew(name, duration, 0, 0);\\n    }\\n\\n    function renewWithFuses(\\n        string calldata name,\\n        uint256 duration,\\n        uint32 fuses,\\n        uint64 wrapperExpiry\\n    ) external payable {\\n        bytes32 labelhash = keccak256(bytes(name));\\n        bytes32 nodehash = keccak256(abi.encodePacked(ETH_NODE, labelhash));\\n        if (!nameWrapper.isTokenOwnerOrApproved(nodehash, msg.sender)) {\\n            revert Unauthorised(nodehash);\\n        }\\n        _renew(name, duration, fuses, wrapperExpiry);\\n    }\\n\\n    function _renew(\\n        string calldata name,\\n        uint256 duration,\\n        uint32 fuses,\\n        uint64 wrapperExpiry\\n    ) internal {\\n        bytes32 labelhash = keccak256(bytes(name));\\n        bytes32 nodehash = keccak256(abi.encodePacked(ETH_NODE, labelhash));\\n        uint256 tokenId = uint256(labelhash);\\n        IPriceOracle.Price memory price = rentPrice(name, duration);\\n        if (msg.value < price.base) {\\n            revert InsufficientValue();\\n        }\\n        uint256 expires;\\n        if (nameWrapper.isWrapped(nodehash)) {\\n            expires = nameWrapper.renew(\\n                tokenId,\\n                duration,\\n                fuses,\\n                wrapperExpiry\\n            );\\n        } else {\\n            expires = base.renew(tokenId, duration);\\n        }\\n\\n        if (msg.value > price.base) {\\n            payable(msg.sender).transfer(msg.value - price.base);\\n        }\\n\\n        emit NameRenewed(name, labelhash, msg.value, expires);\\n    }\\n\\n    function withdraw() public {\\n        payable(owner()).transfer(address(this).balance);\\n    }\\n\\n    function supportsInterface(bytes4 interfaceID)\\n        external\\n        pure\\n        returns (bool)\\n    {\\n        return\\n            interfaceID == type(IERC165).interfaceId ||\\n            interfaceID == type(IETHRegistrarController).interfaceId;\\n    }\\n\\n    /* Internal functions */\\n\\n    function _consumeCommitment(\\n        string memory name,\\n        uint256 duration,\\n        bytes32 commitment\\n    ) internal {\\n        // Require an old enough commitment.\\n        if (commitments[commitment] + minCommitmentAge > block.timestamp) {\\n            revert CommitmentTooNew(commitment);\\n        }\\n\\n        // If the commitment is too old, or the name is registered, stop\\n        if (commitments[commitment] + maxCommitmentAge <= block.timestamp) {\\n            revert CommitmentTooOld(commitment);\\n        }\\n        if (!available(name)) {\\n            revert NameNotAvailable(name);\\n        }\\n\\n        delete (commitments[commitment]);\\n\\n        if (duration < MIN_REGISTRATION_DURATION) {\\n            revert DurationTooShort(duration);\\n        }\\n    }\\n\\n    function _setRecords(\\n        address resolverAddress,\\n        bytes32 label,\\n        bytes[] calldata data\\n    ) internal {\\n        // use hardcoded .eth namehash\\n        bytes32 nodehash = keccak256(abi.encodePacked(ETH_NODE, label));\\n        Resolver resolver = Resolver(resolverAddress);\\n        resolver.multicallWithNodeCheck(nodehash, data);\\n    }\\n\\n    function _setReverseRecord(\\n        string memory name,\\n        address resolver,\\n        address owner\\n    ) internal {\\n        reverseRegistrar.setNameForAddr(\\n            msg.sender,\\n            owner,\\n            resolver,\\n            string.concat(name, \\\".eth\\\")\\n        );\\n    }\\n}\\n\",\"keccak256\":\"0x88fa793320fc7f510b0b3a9286664b8ac76c5b27da90b25d370854757b0dfecd\",\"license\":\"MIT\"},\"contracts/ethregistrar/IBaseRegistrar.sol\":{\"content\":\"import \\\"../registry/ENS.sol\\\";\\nimport \\\"./IBaseRegistrar.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\ninterface IBaseRegistrar is IERC721 {\\n    event ControllerAdded(address indexed controller);\\n    event ControllerRemoved(address indexed controller);\\n    event NameMigrated(\\n        uint256 indexed id,\\n        address indexed owner,\\n        uint256 expires\\n    );\\n    event NameRegistered(\\n        uint256 indexed id,\\n        address indexed owner,\\n        uint256 expires\\n    );\\n    event NameRenewed(uint256 indexed id, uint256 expires);\\n\\n    // Authorises a controller, who can register and renew domains.\\n    function addController(address controller) external;\\n\\n    // Revoke controller permission for an address.\\n    function removeController(address controller) external;\\n\\n    // Set the resolver for the TLD this registrar manages.\\n    function setResolver(address resolver) external;\\n\\n    // Returns the expiration timestamp of the specified label hash.\\n    function nameExpires(uint256 id) external view returns (uint256);\\n\\n    // Returns true iff the specified name is available for registration.\\n    function available(uint256 id) external view returns (bool);\\n\\n    /**\\n     * @dev Register a name.\\n     */\\n    function register(\\n        uint256 id,\\n        address owner,\\n        uint256 duration\\n    ) external returns (uint256);\\n\\n    function renew(uint256 id, uint256 duration) external returns (uint256);\\n\\n    /**\\n     * @dev Reclaim ownership of a name in ENS, if you own it in the registrar.\\n     */\\n    function reclaim(uint256 id, address owner) external;\\n}\\n\",\"keccak256\":\"0x9ac51351ff72d73083aed62b7cdad4c07e9d1eb68401d7fd8457bdd828f2c6fe\"},\"contracts/ethregistrar/IETHRegistrarController.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nimport \\\"./IPriceOracle.sol\\\";\\n\\ninterface IETHRegistrarController {\\n    function rentPrice(string memory, uint256)\\n        external\\n        returns (IPriceOracle.Price memory);\\n\\n    function available(string memory) external returns (bool);\\n\\n    function makeCommitment(\\n        string memory,\\n        address,\\n        uint256,\\n        bytes32,\\n        address,\\n        bytes[] calldata,\\n        bool,\\n        uint32,\\n        uint64\\n    ) external returns (bytes32);\\n\\n    function commit(bytes32) external;\\n\\n    function register(\\n        string calldata,\\n        address,\\n        uint256,\\n        bytes32,\\n        address,\\n        bytes[] calldata,\\n        bool,\\n        uint32,\\n        uint64\\n    ) external payable;\\n\\n    function renew(string calldata, uint256) external payable;\\n}\\n\",\"keccak256\":\"0x999c1c3386cfef6a52b86b33a45820d551366141db8c5915740895c9f2425772\",\"license\":\"MIT\"},\"contracts/ethregistrar/IPriceOracle.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\ninterface IPriceOracle {\\n    struct Price {\\n        uint256 base;\\n        uint256 premium;\\n    }\\n\\n    /**\\n     * @dev Returns the price to register or renew a name.\\n     * @param name The name being registered or renewed.\\n     * @param expires When the name presently expires (0 if this is a new registration).\\n     * @param duration How long the name is being registered or extended for, in seconds.\\n     * @return base premium tuple of base price + premium price\\n     */\\n    function price(\\n        string calldata name,\\n        uint256 expires,\\n        uint256 duration\\n    ) external view returns (Price calldata);\\n}\\n\",\"keccak256\":\"0x1ec537b4c7f9cc40363b39dcc7ade8c29bf94662e6b01d38e681487637bd577e\",\"license\":\"MIT\"},\"contracts/ethregistrar/StringUtils.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\nlibrary StringUtils {\\n    /**\\n     * @dev Returns the length of a given string\\n     *\\n     * @param s The string to measure the length of\\n     * @return The length of the input string\\n     */\\n    function strlen(string memory s) internal pure returns (uint256) {\\n        uint256 len;\\n        uint256 i = 0;\\n        uint256 bytelength = bytes(s).length;\\n        for (len = 0; i < bytelength; len++) {\\n            bytes1 b = bytes(s)[i];\\n            if (b < 0x80) {\\n                i += 1;\\n            } else if (b < 0xE0) {\\n                i += 2;\\n            } else if (b < 0xF0) {\\n                i += 3;\\n            } else if (b < 0xF8) {\\n                i += 4;\\n            } else if (b < 0xFC) {\\n                i += 5;\\n            } else {\\n                i += 6;\\n            }\\n        }\\n        return len;\\n    }\\n}\\n\",\"keccak256\":\"0x4cc8363a850dc9130c433ee50e7c97e29a45ae5d9bd0808205ac7134b34f24e4\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n    // Logged when the owner of a node assigns a new owner to a subnode.\\n    event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n    // Logged when the owner of a node transfers ownership to a new account.\\n    event Transfer(bytes32 indexed node, address owner);\\n\\n    // Logged when the resolver for a node changes.\\n    event NewResolver(bytes32 indexed node, address resolver);\\n\\n    // Logged when the TTL of a node changes\\n    event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n    // Logged when an operator is added or removed.\\n    event ApprovalForAll(\\n        address indexed owner,\\n        address indexed operator,\\n        bool approved\\n    );\\n\\n    function setRecord(\\n        bytes32 node,\\n        address owner,\\n        address resolver,\\n        uint64 ttl\\n    ) external;\\n\\n    function setSubnodeRecord(\\n        bytes32 node,\\n        bytes32 label,\\n        address owner,\\n        address resolver,\\n        uint64 ttl\\n    ) external;\\n\\n    function setSubnodeOwner(\\n        bytes32 node,\\n        bytes32 label,\\n        address owner\\n    ) external returns (bytes32);\\n\\n    function setResolver(bytes32 node, address resolver) external;\\n\\n    function setOwner(bytes32 node, address owner) external;\\n\\n    function setTTL(bytes32 node, uint64 ttl) external;\\n\\n    function setApprovalForAll(address operator, bool approved) external;\\n\\n    function owner(bytes32 node) external view returns (address);\\n\\n    function resolver(bytes32 node) external view returns (address);\\n\\n    function ttl(bytes32 node) external view returns (uint64);\\n\\n    function recordExists(bytes32 node) external view returns (bool);\\n\\n    function isApprovedForAll(address owner, address operator)\\n        external\\n        view\\n        returns (bool);\\n}\\n\",\"keccak256\":\"0xf79be82c1a2eb0a77fba4e0972221912e803309081ca460fd2cf61653e55758a\"},\"contracts/registry/IReverseRegistrar.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface IReverseRegistrar {\\n    function setDefaultResolver(address resolver) external;\\n\\n    function claim(address owner) external returns (bytes32);\\n\\n    function claimForAddr(\\n        address addr,\\n        address owner,\\n        address resolver\\n    ) external returns (bytes32);\\n\\n    function claimWithResolver(address owner, address resolver)\\n        external\\n        returns (bytes32);\\n\\n    function setName(string memory name) external returns (bytes32);\\n\\n    function setNameForAddr(\\n        address addr,\\n        address owner,\\n        address resolver,\\n        string memory name\\n    ) external returns (bytes32);\\n\\n    function node(address addr) external pure returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd6ba83973ffbab31dec17a716af3bb5703844d16dceb5078583fb2c509f8bcc2\"},\"contracts/registry/ReverseRegistrar.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\nimport \\\"./ENS.sol\\\";\\nimport \\\"./IReverseRegistrar.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"../root/Controllable.sol\\\";\\n\\nabstract contract NameResolver {\\n    function setName(bytes32 node, string memory name) public virtual;\\n}\\n\\nbytes32 constant lookup = 0x3031323334353637383961626364656600000000000000000000000000000000;\\n\\nbytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;\\n\\n// namehash('addr.reverse')\\n\\ncontract ReverseRegistrar is Ownable, Controllable, IReverseRegistrar {\\n    ENS public immutable ens;\\n    NameResolver public defaultResolver;\\n\\n    event ReverseClaimed(address indexed addr, bytes32 indexed node);\\n    event DefaultResolverChanged(NameResolver indexed resolver);\\n\\n    /**\\n     * @dev Constructor\\n     * @param ensAddr The address of the ENS registry.\\n     */\\n    constructor(ENS ensAddr) {\\n        ens = ensAddr;\\n\\n        // Assign ownership of the reverse record to our deployer\\n        ReverseRegistrar oldRegistrar = ReverseRegistrar(\\n            ensAddr.owner(ADDR_REVERSE_NODE)\\n        );\\n        if (address(oldRegistrar) != address(0x0)) {\\n            oldRegistrar.claim(msg.sender);\\n        }\\n    }\\n\\n    modifier authorised(address addr) {\\n        require(\\n            addr == msg.sender ||\\n                controllers[msg.sender] ||\\n                ens.isApprovedForAll(addr, msg.sender) ||\\n                ownsContract(addr),\\n            \\\"ReverseRegistrar: Caller is not a controller or authorised by address or the address itself\\\"\\n        );\\n        _;\\n    }\\n\\n    function setDefaultResolver(address resolver) public override onlyOwner {\\n        require(\\n            address(resolver) != address(0),\\n            \\\"ReverseRegistrar: Resolver address must not be 0\\\"\\n        );\\n        defaultResolver = NameResolver(resolver);\\n        emit DefaultResolverChanged(NameResolver(resolver));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the reverse ENS record associated with the\\n     *      calling account.\\n     * @param owner The address to set as the owner of the reverse record in ENS.\\n     * @return The ENS node hash of the reverse record.\\n     */\\n    function claim(address owner) public override returns (bytes32) {\\n        return claimForAddr(msg.sender, owner, address(defaultResolver));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the reverse ENS record associated with the\\n     *      calling account.\\n     * @param addr The reverse record to set\\n     * @param owner The address to set as the owner of the reverse record in ENS.\\n     * @param resolver The resolver of the reverse node\\n     * @return The ENS node hash of the reverse record.\\n     */\\n    function claimForAddr(\\n        address addr,\\n        address owner,\\n        address resolver\\n    ) public override authorised(addr) returns (bytes32) {\\n        bytes32 labelHash = sha3HexAddress(addr);\\n        bytes32 reverseNode = keccak256(\\n            abi.encodePacked(ADDR_REVERSE_NODE, labelHash)\\n        );\\n        emit ReverseClaimed(addr, reverseNode);\\n        ens.setSubnodeRecord(ADDR_REVERSE_NODE, labelHash, owner, resolver, 0);\\n        return reverseNode;\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the reverse ENS record associated with the\\n     *      calling account.\\n     * @param owner The address to set as the owner of the reverse record in ENS.\\n     * @param resolver The address of the resolver to set; 0 to leave unchanged.\\n     * @return The ENS node hash of the reverse record.\\n     */\\n    function claimWithResolver(address owner, address resolver)\\n        public\\n        override\\n        returns (bytes32)\\n    {\\n        return claimForAddr(msg.sender, owner, resolver);\\n    }\\n\\n    /**\\n     * @dev Sets the `name()` record for the reverse ENS record associated with\\n     * the calling account. First updates the resolver to the default reverse\\n     * resolver if necessary.\\n     * @param name The name to set for this address.\\n     * @return The ENS node hash of the reverse record.\\n     */\\n    function setName(string memory name) public override returns (bytes32) {\\n        return\\n            setNameForAddr(\\n                msg.sender,\\n                msg.sender,\\n                address(defaultResolver),\\n                name\\n            );\\n    }\\n\\n    /**\\n     * @dev Sets the `name()` record for the reverse ENS record associated with\\n     * the account provided. Updates the resolver to a designated resolver\\n     * Only callable by controllers and authorised users\\n     * @param addr The reverse record to set\\n     * @param owner The owner of the reverse node\\n     * @param resolver The resolver of the reverse node\\n     * @param name The name to set for this address.\\n     * @return The ENS node hash of the reverse record.\\n     */\\n    function setNameForAddr(\\n        address addr,\\n        address owner,\\n        address resolver,\\n        string memory name\\n    ) public override returns (bytes32) {\\n        bytes32 node = claimForAddr(addr, owner, resolver);\\n        NameResolver(resolver).setName(node, name);\\n        return node;\\n    }\\n\\n    /**\\n     * @dev Returns the node hash for a given account's reverse records.\\n     * @param addr The address to hash\\n     * @return The ENS node hash.\\n     */\\n    function node(address addr) public pure override returns (bytes32) {\\n        return\\n            keccak256(\\n                abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(addr))\\n            );\\n    }\\n\\n    /**\\n     * @dev An optimised function to compute the sha3 of the lower-case\\n     *      hexadecimal representation of an Ethereum address.\\n     * @param addr The address to hash\\n     * @return ret The SHA3 hash of the lower-case hexadecimal encoding of the\\n     *         input address.\\n     */\\n    function sha3HexAddress(address addr) private pure returns (bytes32 ret) {\\n        assembly {\\n            for {\\n                let i := 40\\n            } gt(i, 0) {\\n\\n            } {\\n                i := sub(i, 1)\\n                mstore8(i, byte(and(addr, 0xf), lookup))\\n                addr := div(addr, 0x10)\\n                i := sub(i, 1)\\n                mstore8(i, byte(and(addr, 0xf), lookup))\\n                addr := div(addr, 0x10)\\n            }\\n\\n            ret := keccak256(0, 40)\\n        }\\n    }\\n\\n    function ownsContract(address addr) internal view returns (bool) {\\n        try Ownable(addr).owner() returns (address owner) {\\n            return owner == msg.sender;\\n        } catch {\\n            return false;\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x4430930561750d2de1163f7b7ba22ae003a7684394371e90a04374859a2337cf\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n    IERC165,\\n    IABIResolver,\\n    IAddressResolver,\\n    IAddrResolver,\\n    IContentHashResolver,\\n    IDNSRecordResolver,\\n    IDNSZoneResolver,\\n    IInterfaceResolver,\\n    INameResolver,\\n    IPubkeyResolver,\\n    ITextResolver,\\n    IExtendedResolver\\n{\\n    /* Deprecated events */\\n    event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n    function setABI(\\n        bytes32 node,\\n        uint256 contentType,\\n        bytes calldata data\\n    ) external;\\n\\n    function setAddr(bytes32 node, address addr) external;\\n\\n    function setAddr(\\n        bytes32 node,\\n        uint256 coinType,\\n        bytes calldata a\\n    ) external;\\n\\n    function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n    function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n    function setName(bytes32 node, string calldata _name) external;\\n\\n    function setPubkey(\\n        bytes32 node,\\n        bytes32 x,\\n        bytes32 y\\n    ) external;\\n\\n    function setText(\\n        bytes32 node,\\n        string calldata key,\\n        string calldata value\\n    ) external;\\n\\n    function setInterface(\\n        bytes32 node,\\n        bytes4 interfaceID,\\n        address implementer\\n    ) external;\\n\\n    function multicall(bytes[] calldata data)\\n        external\\n        returns (bytes[] memory results);\\n\\n    function multicallWithNodeCheck(bytes32 nodehash, bytes[] calldata data)\\n        external\\n        returns (bytes[] memory results);\\n\\n    /* Deprecated functions */\\n    function content(bytes32 node) external view returns (bytes32);\\n\\n    function multihash(bytes32 node) external view returns (bytes memory);\\n\\n    function setContent(bytes32 node, bytes32 hash) external;\\n\\n    function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0x73b6cd44b0ed803083996abd3d2683f2444731b6486045f8274c44fce66bf939\",\"license\":\"MIT\"},\"contracts/resolvers/ResolverBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport \\\"./profiles/IVersionableResolver.sol\\\";\\n\\nabstract contract ResolverBase is ERC165, IVersionableResolver {\\n    mapping(bytes32 => uint64) public recordVersions;\\n\\n    function isAuthorised(bytes32 node) internal view virtual returns (bool);\\n\\n    modifier authorised(bytes32 node) {\\n        require(isAuthorised(node));\\n        _;\\n    }\\n\\n    /**\\n     * Increments the record version associated with an ENS node.\\n     * May only be called by the owner of that node in the ENS registry.\\n     * @param node The node to update.\\n     */\\n    function clearRecords(bytes32 node) public virtual authorised(node) {\\n        recordVersions[node]++;\\n        emit VersionChanged(node, recordVersions[node]);\\n    }\\n\\n    function supportsInterface(bytes4 interfaceID)\\n        public\\n        view\\n        virtual\\n        override\\n        returns (bool)\\n    {\\n        return\\n            interfaceID == type(IVersionableResolver).interfaceId ||\\n            super.supportsInterface(interfaceID);\\n    }\\n}\\n\",\"keccak256\":\"0x99887f8890c62800bfe702dd67e36453a7017f05a368017c1187366bd98bc0a6\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"./IABIResolver.sol\\\";\\nimport \\\"../ResolverBase.sol\\\";\\n\\ninterface IABIResolver {\\n    event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n    /**\\n     * Returns the ABI associated with an ENS node.\\n     * Defined in EIP205.\\n     * @param node The ENS node to query\\n     * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n     * @return contentType The content type of the return value\\n     * @return data The ABI data\\n     */\\n    function ABI(bytes32 node, uint256 contentTypes)\\n        external\\n        view\\n        returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0xc6db25d9b07ea925c64bb777f00ba557e99fbccd4c30c20e5a1b5cd8c159dcbf\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n    event AddrChanged(bytes32 indexed node, address a);\\n\\n    /**\\n     * Returns the address associated with an ENS node.\\n     * @param node The ENS node to query.\\n     * @return The associated address.\\n     */\\n    function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n    event AddressChanged(\\n        bytes32 indexed node,\\n        uint256 coinType,\\n        bytes newAddress\\n    );\\n\\n    function addr(bytes32 node, uint256 coinType)\\n        external\\n        view\\n        returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x37221203e063dee5aa2a067a6ab3401e9cca41cce5b15230994b6ea377f05ed5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n    event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n    /**\\n     * Returns the contenthash associated with an ENS node.\\n     * @param node The ENS node to query.\\n     * @return The associated contenthash.\\n     */\\n    function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n    // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n    event DNSRecordChanged(\\n        bytes32 indexed node,\\n        bytes name,\\n        uint16 resource,\\n        bytes record\\n    );\\n    // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n    event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n    /**\\n     * Obtain a DNS record.\\n     * @param node the namehash of the node for which to fetch the record\\n     * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n     * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n     * @return the DNS record in wire format if present, otherwise empty\\n     */\\n    function dnsRecord(\\n        bytes32 node,\\n        bytes32 name,\\n        uint16 resource\\n    ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n    // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n    event DNSZonehashChanged(\\n        bytes32 indexed node,\\n        bytes lastzonehash,\\n        bytes zonehash\\n    );\\n\\n    /**\\n     * zonehash obtains the hash for the zone.\\n     * @param node The ENS node to query.\\n     * @return The associated contenthash.\\n     */\\n    function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n    function resolve(bytes memory name, bytes memory data)\\n        external\\n        view\\n        returns (bytes memory, address);\\n}\\n\",\"keccak256\":\"0x0a586a1725cdc5f90f2e302c620a4a033adfc87e49bbcc5a43604ba579bce7a7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n    event InterfaceChanged(\\n        bytes32 indexed node,\\n        bytes4 indexed interfaceID,\\n        address implementer\\n    );\\n\\n    /**\\n     * Returns the address of a contract that implements the specified interface for this name.\\n     * If an implementer has not been set for this interfaceID and name, the resolver will query\\n     * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n     * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n     * will be returned.\\n     * @param node The ENS node to query.\\n     * @param interfaceID The EIP 165 interface ID to check for.\\n     * @return The address that implements this interface, or 0 if the interface is unsupported.\\n     */\\n    function interfaceImplementer(bytes32 node, bytes4 interfaceID)\\n        external\\n        view\\n        returns (address);\\n}\\n\",\"keccak256\":\"0x6d75d6010016684030e13711b3bc1a4e1a784c7398937f1b7c2b2f328f962c2b\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n    event NameChanged(bytes32 indexed node, string name);\\n\\n    /**\\n     * Returns the name associated with an ENS node, for reverse records.\\n     * Defined in EIP181.\\n     * @param node The ENS node to query.\\n     * @return The associated name.\\n     */\\n    function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n    event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n    /**\\n     * Returns the SECP256k1 public key associated with an ENS node.\\n     * Defined in EIP 619.\\n     * @param node The ENS node to query\\n     * @return x The X coordinate of the curve point for the public key.\\n     * @return y The Y coordinate of the curve point for the public key.\\n     */\\n    function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n    event TextChanged(\\n        bytes32 indexed node,\\n        string indexed indexedKey,\\n        string key,\\n        string value\\n    );\\n\\n    /**\\n     * Returns the text data associated with an ENS node and key.\\n     * @param node The ENS node to query.\\n     * @param key The text data key to query.\\n     * @return The associated text data.\\n     */\\n    function text(bytes32 node, string calldata key)\\n        external\\n        view\\n        returns (string memory);\\n}\\n\",\"keccak256\":\"0xcc5eada60de63f42f47a4bbc8a5d2bed4cd1394646197a08da7957c6fd90ba5d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IVersionableResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IVersionableResolver {\\n    event VersionChanged(bytes32 indexed node, uint64 newVersion);\\n\\n    function recordVersions(bytes32 node) external view returns (uint64);\\n}\\n\",\"keccak256\":\"0xd0d09596f20c57bafb2ffa8521a8c57120e9af6c6b194f9c689d4da56f91a57c\",\"license\":\"MIT\"},\"contracts/root/Controllable.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\ncontract Controllable is Ownable {\\n    mapping(address => bool) public controllers;\\n\\n    event ControllerChanged(address indexed controller, bool enabled);\\n\\n    modifier onlyController() {\\n        require(\\n            controllers[msg.sender],\\n            \\\"Controllable: Caller is not a controller\\\"\\n        );\\n        _;\\n    }\\n\\n    function setController(address controller, bool enabled) public onlyOwner {\\n        controllers[controller] = enabled;\\n        emit ControllerChanged(controller, enabled);\\n    }\\n}\\n\",\"keccak256\":\"0xb19b8c0fafe9ca2b4bf8aaafee486fa31437672e1e1977bdf84bfe03464969db\"},\"contracts/utils/ERC20Recoverable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n    @notice Contract is used to recover ERC20 tokens sent to the contract by mistake.\\n */\\n\\ncontract ERC20Recoverable is Ownable {\\n    /**\\n    @notice Recover ERC20 tokens sent to the contract by mistake.\\n    @dev The contract is Ownable and only the owner can call the recover function.\\n    @param _to The address to send the tokens to.\\n@param _token The address of the ERC20 token to recover\\n    @param _amount The amount of tokens to recover.\\n */\\n    function recoverFunds(\\n        address _token,\\n        address _to,\\n        uint256 _amount\\n    ) external onlyOwner {\\n        IERC20(_token).transfer(_to, _amount);\\n    }\\n}\\n\",\"keccak256\":\"0x793a38091e1f81499a29ddba82c2b2f3cdd07071b81a832886e8e02a45ff352a\",\"license\":\"MIT\"},\"contracts/wrapper/IMetadataService.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\ninterface IMetadataService {\\n    function uri(uint256) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0xb3f1cf6df01ed7b15e5f2318f6823afbdb586ca38c2124c67955c645647ae9a2\",\"license\":\"MIT\"},\"contracts/wrapper/INameWrapper.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nimport \\\"../registry/ENS.sol\\\";\\nimport \\\"../ethregistrar/IBaseRegistrar.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\nimport \\\"./IMetadataService.sol\\\";\\n\\nuint32 constant CANNOT_UNWRAP = 1;\\nuint32 constant CANNOT_BURN_FUSES = 2;\\nuint32 constant CANNOT_TRANSFER = 4;\\nuint32 constant CANNOT_SET_RESOLVER = 8;\\nuint32 constant CANNOT_SET_TTL = 16;\\nuint32 constant CANNOT_CREATE_SUBDOMAIN = 32;\\nuint32 constant PARENT_CANNOT_CONTROL = 64;\\nuint32 constant CAN_DO_EVERYTHING = 0;\\n\\ninterface INameWrapper is IERC1155 {\\n    event NameWrapped(\\n        bytes32 indexed node,\\n        bytes name,\\n        address owner,\\n        uint32 fuses,\\n        uint64 expiry\\n    );\\n\\n    event NameUnwrapped(bytes32 indexed node, address owner);\\n\\n    event FusesSet(bytes32 indexed node, uint32 fuses, uint64 expiry);\\n\\n    function ens() external view returns (ENS);\\n\\n    function registrar() external view returns (IBaseRegistrar);\\n\\n    function metadataService() external view returns (IMetadataService);\\n\\n    function names(bytes32) external view returns (bytes memory);\\n\\n    function wrap(\\n        bytes calldata name,\\n        address wrappedOwner,\\n        address resolver\\n    ) external;\\n\\n    function wrapETH2LD(\\n        string calldata label,\\n        address wrappedOwner,\\n        uint32 fuses,\\n        uint64 _expiry,\\n        address resolver\\n    ) external returns (uint64 expiry);\\n\\n    function registerAndWrapETH2LD(\\n        string calldata label,\\n        address wrappedOwner,\\n        uint256 duration,\\n        address resolver,\\n        uint32 fuses,\\n        uint64 expiry\\n    ) external returns (uint256 registrarExpiry);\\n\\n    function renew(\\n        uint256 labelHash,\\n        uint256 duration,\\n        uint32 fuses,\\n        uint64 expiry\\n    ) external returns (uint256 expires);\\n\\n    function unwrap(\\n        bytes32 node,\\n        bytes32 label,\\n        address owner\\n    ) external;\\n\\n    function unwrapETH2LD(\\n        bytes32 label,\\n        address newRegistrant,\\n        address newController\\n    ) external;\\n\\n    function setFuses(bytes32 node, uint32 fuses)\\n        external\\n        returns (uint32 newFuses);\\n\\n    function setChildFuses(\\n        bytes32 parentNode,\\n        bytes32 labelhash,\\n        uint32 fuses,\\n        uint64 expiry\\n    ) external;\\n\\n    function setSubnodeRecord(\\n        bytes32 node,\\n        string calldata label,\\n        address owner,\\n        address resolver,\\n        uint64 ttl,\\n        uint32 fuses,\\n        uint64 expiry\\n    ) external returns (bytes32);\\n\\n    function setRecord(\\n        bytes32 node,\\n        address owner,\\n        address resolver,\\n        uint64 ttl\\n    ) external;\\n\\n    function setSubnodeOwner(\\n        bytes32 node,\\n        string calldata label,\\n        address newOwner,\\n        uint32 fuses,\\n        uint64 expiry\\n    ) external returns (bytes32);\\n\\n    function isTokenOwnerOrApproved(bytes32 node, address addr)\\n        external\\n        returns (bool);\\n\\n    function setResolver(bytes32 node, address resolver) external;\\n\\n    function setTTL(bytes32 node, uint64 ttl) external;\\n\\n    function ownerOf(uint256 id) external returns (address owner);\\n\\n    function getData(uint256 id)\\n        external\\n        returns (\\n            address,\\n            uint32,\\n            uint64\\n        );\\n\\n    function allFusesBurned(bytes32 node, uint32 fuseMask)\\n        external\\n        view\\n        returns (bool);\\n\\n    function isWrapped(bytes32 node) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x9c0ff4675d7faf51638138ecfc76a1f50c1005d1005bfba31c1cac7990a43c30\",\"license\":\"MIT\"}},\"version\":1}",
  "bytecode": "0x6101406040523480156200001257600080fd5b50604051620027783803806200277883398101604081905262000035916200011a565b6200004033620000b1565b83831162000061576040516307cb550760e31b815260040160405180910390fd5b428311156200008357604051630b4319e560e21b815260040160405180910390fd5b6001600160a01b0395861660805293851660a05260c09290925260e052821661010052166101205262000197565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200011757600080fd5b50565b60008060008060008060c087890312156200013457600080fd5b8651620001418162000101565b6020880151909650620001548162000101565b8095505060408701519350606087015192506080870151620001768162000101565b60a0880151909250620001898162000101565b809150509295509295509295565b60805160a05160c05160e0516101005161012051612544620002346000396000818161038d0152818161074f015281816109e4015281816111bc015261129301526000818161022801526117410152600081816103f401528181610f03015261156901526000818161030e01526114f20152600081816104280152610c30015260008181610c7201528181610db7015261135201526125446000f3fe60806040526004361061016a5760003560e01c80638d839ffe116100cb578063aeb8ce9b1161007f578063d555254a11610059578063d555254a1461044a578063f14fcbc81461046a578063f2fde38b1461048a57600080fd5b8063aeb8ce9b146103c2578063ce1e09c0146103e2578063d3419bf31461041657600080fd5b80639791c097116100b05780639791c0971461035b578063a8e5fbc01461037b578063acf1a841146103af57600080fd5b80638d839ffe146102fc5780638da5cb5b1461033057600080fd5b80637acaaf2611610122578063839df94511610107578063839df9451461026f57806383e7f6ff146102aa5780638a95b09f146102e557600080fd5b80637acaaf2614610203578063808698531461021657600080fd5b80635d3590d5116101535780635d3590d5146101bb5780636459220f146101db578063715018a6146101ee57600080fd5b806301ffc9a71461016f5780633ccfd60b146101a4575b600080fd5b34801561017b57600080fd5b5061018f61018a366004611a07565b6104aa565b60405190151581526020015b60405180910390f35b3480156101b057600080fd5b506101b9610543565b005b3480156101c757600080fd5b506101b96101d6366004611a72565b61058d565b6101b96101e9366004611b23565b6106b2565b3480156101fa57600080fd5b506101b9610820565b6101b9610211366004611be4565b6108ad565b34801561022257600080fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b34801561027b57600080fd5b5061029c61028a366004611cbd565b60016020526000908152604090205481565b60405190815260200161019b565b3480156102b657600080fd5b506102ca6102c5366004611db4565b610be6565b6040805182518152602092830151928101929092520161019b565b3480156102f157600080fd5b5061029c6224ea0081565b34801561030857600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561033c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661024a565b34801561036757600080fd5b5061018f610376366004611df9565b610d46565b34801561038757600080fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b6101b96103bd366004611e2e565b610d5b565b3480156103ce57600080fd5b5061018f6103dd366004611df9565b610d6e565b3480156103ee57600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561042257600080fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561045657600080fd5b5061029c610465366004611e7a565b610e3e565b34801561047657600080fd5b506101b9610485366004611cbd565b610eec565b34801561049657600080fd5b506101b96104a5366004611f4d565b610f75565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061053d57507fffffffff0000000000000000000000000000000000000000000000000000000082167fdf7ed18100000000000000000000000000000000000000000000000000000000145b92915050565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116914780156108fc02929091818181858888f1935050505015801561058a573d6000803e3d6000fd5b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ac9190611f68565b50505050565b600085856040516106c4929190611f85565b604080519182900382207f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae6020840152908201819052915060009060600160408051808303601f190181529082905280516020909101207ff44779b90000000000000000000000000000000000000000000000000000000082526004820181905233602483015291507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063f44779b9906044016020604051808303816000875af11580156107ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d19190611f68565b61080a576040517fe4fd57ae0000000000000000000000000000000000000000000000000000000081526004810182905260240161060a565b61081787878787876110a2565b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060a565b6108ab6000611466565b565b60006108f08c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d9250610be6915050565b6020810151815191925061090391611fc4565b34101561093c576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109e08c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508a6109db8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8e8e8e8e8e8e8e8e610e3e565b6114db565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639f56dac68e8e8e8e8d8a8a6040518863ffffffff1660e01b8152600401610a479796959493929190612002565b6020604051808303816000875af1158015610a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8a919061206c565b90508515610ab557610ab5888e8e604051610aa6929190611f85565b60405180910390208989611658565b8415610afe57610afe8d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c925033915061173f9050565b8a73ffffffffffffffffffffffffffffffffffffffff168d8d604051610b25929190611f85565b60405180910390207f69e37f151eb98a09618ddaa80c8cfaf1ce5996867c489f45b555b412271ebf278f8f8660000151876020015187604051610b6c959493929190612085565b60405180910390a360208201518251610b859190611fc4565b341115610bd7576020820151825133916108fc91610ba39190611fc4565b610bad90346120b6565b6040518115909202916000818181858888f19350505050158015610bd5573d6000803e3d6000fd5b505b50505050505050505050505050565b6040805180820190915260008082526020820152825160208401206040517fd6e4fa86000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116916350e9a7159187917f00000000000000000000000000000000000000000000000000000000000000009091169063d6e4fa8690602401602060405180830381865afa158015610cbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cdf919061206c565b866040518463ffffffff1660e01b8152600401610cfe93929190612119565b6040805180830381865afa158015610d1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3e919061213e565b949350505050565b60006003610d5383611800565b101592915050565b610d698383836000806110a2565b505050565b80516020820120600090610d8183610d46565b8015610e3757506040517f96e494e8000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906396e494e890602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190611f68565b9392505050565b895160208b01206000908515801590610e6b575073ffffffffffffffffffffffffffffffffffffffff8816155b15610ea2576040517fd3f605c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808b8b8a8a8a8e8b8b8b604051602001610ec59a9998979695949392919061223d565b604051602081830303815290604052805190602001209150509a9950505050505050505050565b6000818152600160205260409020544290610f28907f000000000000000000000000000000000000000000000000000000000000000090611fc4565b10610f62576040517f0a059d710000000000000000000000000000000000000000000000000000000081526004810182905260240161060a565b6000908152600160205260409020429055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060a565b73ffffffffffffffffffffffffffffffffffffffff8116611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161060a565b61058a81611466565b600085856040516110b4929190611f85565b604080519182900382207f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae6020840152908201819052915060009060600160408051601f198184030181528282528051602091820120601f8a01829004820284018201909252888352909250839160009161114c91908b908b90819084018382808284376000920191909152508b9250610be6915050565b805190915034101561118a576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ffd0cd0d9000000000000000000000000000000000000000000000000000000008152600481018490526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063fd0cd0d990602401602060405180830381865afa158015611218573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123c9190611f68565b1561131c576040517f47d2e9fe000000000000000000000000000000000000000000000000000000008152600481018490526024810189905263ffffffff8816604482015267ffffffffffffffff871660648201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906347d2e9fe906084016020604051808303816000875af11580156112f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611315919061206c565b90506113d7565b6040517fc475abff00000000000000000000000000000000000000000000000000000000815260048101849052602481018990527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c475abff906044016020604051808303816000875af11580156113b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d4919061206c565b90505b815134111561141c57815133906108fc906113f290346120b6565b6040518115909202916000818181858888f1935050505015801561141a573d6000803e3d6000fd5b505b847f3da24c024582931cfaf8267d8ed24d13a82a8068d5bd337d30ec45cea4e506ae8b8b348560405161145294939291906122bf565b60405180910390a250505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000818152600160205260409020544290611517907f000000000000000000000000000000000000000000000000000000000000000090611fc4565b1115611552576040517f5320bcf90000000000000000000000000000000000000000000000000000000081526004810182905260240161060a565b600081815260016020526040902054429061158e907f000000000000000000000000000000000000000000000000000000000000000090611fc4565b116115c8576040517fcb7690d70000000000000000000000000000000000000000000000000000000081526004810182905260240161060a565b6115d183610d6e565b61160957826040517f477707e800000000000000000000000000000000000000000000000000000000815260040161060a91906122e6565b6000818152600160205260408120556224ea00821015610d69576040517f9a71997b0000000000000000000000000000000000000000000000000000000081526004810183905260240161060a565b604080517f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae602080830191909152818301869052825180830384018152606083019384905280519101207fe32954eb00000000000000000000000000000000000000000000000000000000909252859073ffffffffffffffffffffffffffffffffffffffff82169063e32954eb906116f8908590889088906064016122f9565b6000604051808303816000875af1158015611717573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610817919081019061231c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637a806d6b3383858760405160200161178f919061241b565b6040516020818303038152906040526040518563ffffffff1660e01b81526004016117bd949392919061245c565b6020604051808303816000875af11580156117dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ac919061206c565b8051600090819081905b808210156119fe576000858381518110611826576118266124a7565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690507f800000000000000000000000000000000000000000000000000000000000000081101561188957611882600184611fc4565b92506119eb565b7fe0000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156118de57611882600284611fc4565b7ff0000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216101561193357611882600384611fc4565b7ff8000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216101561198857611882600484611fc4565b7ffc000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156119dd57611882600584611fc4565b6119e8600684611fc4565b92505b50826119f6816124d6565b93505061180a565b50909392505050565b600060208284031215611a1957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e3757600080fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114611a6d57600080fd5b919050565b600080600060608486031215611a8757600080fd5b611a9084611a49565b9250611a9e60208501611a49565b9150604084013590509250925092565b60008083601f840112611ac057600080fd5b50813567ffffffffffffffff811115611ad857600080fd5b602083019150836020828501011115611af057600080fd5b9250929050565b803563ffffffff81168114611a6d57600080fd5b803567ffffffffffffffff81168114611a6d57600080fd5b600080600080600060808688031215611b3b57600080fd5b853567ffffffffffffffff811115611b5257600080fd5b611b5e88828901611aae565b90965094505060208601359250611b7760408701611af7565b9150611b8560608701611b0b565b90509295509295909350565b60008083601f840112611ba357600080fd5b50813567ffffffffffffffff811115611bbb57600080fd5b6020830191508360208260051b8501011115611af057600080fd5b801515811461058a57600080fd5b60008060008060008060008060008060006101208c8e031215611c0657600080fd5b67ffffffffffffffff808d351115611c1d57600080fd5b611c2a8e8e358f01611aae565b909c509a50611c3b60208e01611a49565b995060408d0135985060608d01359750611c5760808e01611a49565b96508060a08e01351115611c6a57600080fd5b50611c7b8d60a08e01358e01611b91565b909550935060c08c0135611c8e81611bd6565b9250611c9c60e08d01611af7565b9150611cab6101008d01611b0b565b90509295989b509295989b9093969950565b600060208284031215611ccf57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611d2e57611d2e611cd6565b604052919050565b600067ffffffffffffffff821115611d5057611d50611cd6565b50601f01601f191660200190565b600082601f830112611d6f57600080fd5b8135611d82611d7d82611d36565b611d05565b818152846020838601011115611d9757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215611dc757600080fd5b823567ffffffffffffffff811115611dde57600080fd5b611dea85828601611d5e565b95602094909401359450505050565b600060208284031215611e0b57600080fd5b813567ffffffffffffffff811115611e2257600080fd5b610d3e84828501611d5e565b600080600060408486031215611e4357600080fd5b833567ffffffffffffffff811115611e5a57600080fd5b611e6686828701611aae565b909790965060209590950135949350505050565b6000806000806000806000806000806101208b8d031215611e9a57600080fd5b8a3567ffffffffffffffff80821115611eb257600080fd5b611ebe8e838f01611d5e565b9b50611ecc60208e01611a49565b9a5060408d0135995060608d01359850611ee860808e01611a49565b975060a08d0135915080821115611efe57600080fd5b50611f0b8d828e01611b91565b90965094505060c08b0135611f1f81611bd6565b9250611f2d60e08c01611af7565b9150611f3c6101008c01611b0b565b90509295989b9194979a5092959850565b600060208284031215611f5f57600080fd5b610e3782611a49565b600060208284031215611f7a57600080fd5b8151610e3781611bd6565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561053d5761053d611f95565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60c08152600061201660c08301898b611fd7565b905073ffffffffffffffffffffffffffffffffffffffff808816602084015286604084015280861660608401525063ffffffff8416608083015267ffffffffffffffff831660a083015298975050505050505050565b60006020828403121561207e57600080fd5b5051919050565b608081526000612099608083018789611fd7565b602083019590955250604081019290925260609091015292915050565b8181038181111561053d5761053d611f95565b60005b838110156120e45781810151838201526020016120cc565b50506000910152565b600081518084526121058160208601602086016120c9565b601f01601f19169290920160200192915050565b60608152600061212c60608301866120ed565b60208301949094525060400152919050565b60006040828403121561215057600080fd5b6040516040810181811067ffffffffffffffff8211171561217357612173611cd6565b604052825181526020928301519281019290925250919050565b81835260006020808501808196508560051b810191508460005b8781101561223057828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126121e657600080fd5b8701858101903567ffffffffffffffff81111561220257600080fd5b80360382131561221157600080fd5b61221c868284611fd7565b9a87019a95505050908401906001016121a7565b5091979650505050505050565b60006101208c835273ffffffffffffffffffffffffffffffffffffffff808d1660208501528b6040850152808b16606085015250806080840152612284818401898b61218d565b60a0840197909752505092151560c084015263ffffffff9190911660e083015267ffffffffffffffff16610100909101529695505050505050565b6060815260006122d3606083018688611fd7565b6020830194909452506040015292915050565b602081526000610e3760208301846120ed565b83815260406020820152600061231360408301848661218d565b95945050505050565b6000602080838503121561232f57600080fd5b825167ffffffffffffffff8082111561234757600080fd5b818501915085601f83011261235b57600080fd5b81518181111561236d5761236d611cd6565b8060051b61237c858201611d05565b918252838101850191858101908984111561239657600080fd5b86860192505b8383101561240e578251858111156123b45760008081fd5b8601603f81018b136123c65760008081fd5b8781015160406123d8611d7d83611d36565b8281528d828486010111156123ed5760008081fd5b6123fc838c83018487016120c9565b8552505050918601919086019061239c565b9998505050505050505050565b6000825161242d8184602087016120c9565b7f2e65746800000000000000000000000000000000000000000000000000000000920191825250600401919050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401528085166040840152506080606083015261249d60808301846120ed565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361250757612507611f95565b506001019056fea2646970667358221220d9fb3b87e91578f7a8a6d5440953ca3826801764d1dd460b7339ced1842a0af364736f6c63430008110033",
  "deployedBytecode": "0x60806040526004361061016a5760003560e01c80638d839ffe116100cb578063aeb8ce9b1161007f578063d555254a11610059578063d555254a1461044a578063f14fcbc81461046a578063f2fde38b1461048a57600080fd5b8063aeb8ce9b146103c2578063ce1e09c0146103e2578063d3419bf31461041657600080fd5b80639791c097116100b05780639791c0971461035b578063a8e5fbc01461037b578063acf1a841146103af57600080fd5b80638d839ffe146102fc5780638da5cb5b1461033057600080fd5b80637acaaf2611610122578063839df94511610107578063839df9451461026f57806383e7f6ff146102aa5780638a95b09f146102e557600080fd5b80637acaaf2614610203578063808698531461021657600080fd5b80635d3590d5116101535780635d3590d5146101bb5780636459220f146101db578063715018a6146101ee57600080fd5b806301ffc9a71461016f5780633ccfd60b146101a4575b600080fd5b34801561017b57600080fd5b5061018f61018a366004611a07565b6104aa565b60405190151581526020015b60405180910390f35b3480156101b057600080fd5b506101b9610543565b005b3480156101c757600080fd5b506101b96101d6366004611a72565b61058d565b6101b96101e9366004611b23565b6106b2565b3480156101fa57600080fd5b506101b9610820565b6101b9610211366004611be4565b6108ad565b34801561022257600080fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b34801561027b57600080fd5b5061029c61028a366004611cbd565b60016020526000908152604090205481565b60405190815260200161019b565b3480156102b657600080fd5b506102ca6102c5366004611db4565b610be6565b6040805182518152602092830151928101929092520161019b565b3480156102f157600080fd5b5061029c6224ea0081565b34801561030857600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561033c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661024a565b34801561036757600080fd5b5061018f610376366004611df9565b610d46565b34801561038757600080fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b6101b96103bd366004611e2e565b610d5b565b3480156103ce57600080fd5b5061018f6103dd366004611df9565b610d6e565b3480156103ee57600080fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561042257600080fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561045657600080fd5b5061029c610465366004611e7a565b610e3e565b34801561047657600080fd5b506101b9610485366004611cbd565b610eec565b34801561049657600080fd5b506101b96104a5366004611f4d565b610f75565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061053d57507fffffffff0000000000000000000000000000000000000000000000000000000082167fdf7ed18100000000000000000000000000000000000000000000000000000000145b92915050565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116914780156108fc02929091818181858888f1935050505015801561058a573d6000803e3d6000fd5b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb906044016020604051808303816000875af1158015610688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ac9190611f68565b50505050565b600085856040516106c4929190611f85565b604080519182900382207f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae6020840152908201819052915060009060600160408051808303601f190181529082905280516020909101207ff44779b90000000000000000000000000000000000000000000000000000000082526004820181905233602483015291507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063f44779b9906044016020604051808303816000875af11580156107ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d19190611f68565b61080a576040517fe4fd57ae0000000000000000000000000000000000000000000000000000000081526004810182905260240161060a565b61081787878787876110a2565b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060a565b6108ab6000611466565b565b60006108f08c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d9250610be6915050565b6020810151815191925061090391611fc4565b34101561093c576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109e08c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508a6109db8f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8e8e8e8e8e8e8e8e610e3e565b6114db565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639f56dac68e8e8e8e8d8a8a6040518863ffffffff1660e01b8152600401610a479796959493929190612002565b6020604051808303816000875af1158015610a66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8a919061206c565b90508515610ab557610ab5888e8e604051610aa6929190611f85565b60405180910390208989611658565b8415610afe57610afe8d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c925033915061173f9050565b8a73ffffffffffffffffffffffffffffffffffffffff168d8d604051610b25929190611f85565b60405180910390207f69e37f151eb98a09618ddaa80c8cfaf1ce5996867c489f45b555b412271ebf278f8f8660000151876020015187604051610b6c959493929190612085565b60405180910390a360208201518251610b859190611fc4565b341115610bd7576020820151825133916108fc91610ba39190611fc4565b610bad90346120b6565b6040518115909202916000818181858888f19350505050158015610bd5573d6000803e3d6000fd5b505b50505050505050505050505050565b6040805180820190915260008082526020820152825160208401206040517fd6e4fa86000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116916350e9a7159187917f00000000000000000000000000000000000000000000000000000000000000009091169063d6e4fa8690602401602060405180830381865afa158015610cbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cdf919061206c565b866040518463ffffffff1660e01b8152600401610cfe93929190612119565b6040805180830381865afa158015610d1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3e919061213e565b949350505050565b60006003610d5383611800565b101592915050565b610d698383836000806110a2565b505050565b80516020820120600090610d8183610d46565b8015610e3757506040517f96e494e8000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906396e494e890602401602060405180830381865afa158015610e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e379190611f68565b9392505050565b895160208b01206000908515801590610e6b575073ffffffffffffffffffffffffffffffffffffffff8816155b15610ea2576040517fd3f605c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808b8b8a8a8a8e8b8b8b604051602001610ec59a9998979695949392919061223d565b604051602081830303815290604052805190602001209150509a9950505050505050505050565b6000818152600160205260409020544290610f28907f000000000000000000000000000000000000000000000000000000000000000090611fc4565b10610f62576040517f0a059d710000000000000000000000000000000000000000000000000000000081526004810182905260240161060a565b6000908152600160205260409020429055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ff6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060a565b73ffffffffffffffffffffffffffffffffffffffff8116611099576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161060a565b61058a81611466565b600085856040516110b4929190611f85565b604080519182900382207f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae6020840152908201819052915060009060600160408051601f198184030181528282528051602091820120601f8a01829004820284018201909252888352909250839160009161114c91908b908b90819084018382808284376000920191909152508b9250610be6915050565b805190915034101561118a576040517f1101129400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ffd0cd0d9000000000000000000000000000000000000000000000000000000008152600481018490526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063fd0cd0d990602401602060405180830381865afa158015611218573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123c9190611f68565b1561131c576040517f47d2e9fe000000000000000000000000000000000000000000000000000000008152600481018490526024810189905263ffffffff8816604482015267ffffffffffffffff871660648201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906347d2e9fe906084016020604051808303816000875af11580156112f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611315919061206c565b90506113d7565b6040517fc475abff00000000000000000000000000000000000000000000000000000000815260048101849052602481018990527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c475abff906044016020604051808303816000875af11580156113b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d4919061206c565b90505b815134111561141c57815133906108fc906113f290346120b6565b6040518115909202916000818181858888f1935050505015801561141a573d6000803e3d6000fd5b505b847f3da24c024582931cfaf8267d8ed24d13a82a8068d5bd337d30ec45cea4e506ae8b8b348560405161145294939291906122bf565b60405180910390a250505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000818152600160205260409020544290611517907f000000000000000000000000000000000000000000000000000000000000000090611fc4565b1115611552576040517f5320bcf90000000000000000000000000000000000000000000000000000000081526004810182905260240161060a565b600081815260016020526040902054429061158e907f000000000000000000000000000000000000000000000000000000000000000090611fc4565b116115c8576040517fcb7690d70000000000000000000000000000000000000000000000000000000081526004810182905260240161060a565b6115d183610d6e565b61160957826040517f477707e800000000000000000000000000000000000000000000000000000000815260040161060a91906122e6565b6000818152600160205260408120556224ea00821015610d69576040517f9a71997b0000000000000000000000000000000000000000000000000000000081526004810183905260240161060a565b604080517f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae602080830191909152818301869052825180830384018152606083019384905280519101207fe32954eb00000000000000000000000000000000000000000000000000000000909252859073ffffffffffffffffffffffffffffffffffffffff82169063e32954eb906116f8908590889088906064016122f9565b6000604051808303816000875af1158015611717573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610817919081019061231c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637a806d6b3383858760405160200161178f919061241b565b6040516020818303038152906040526040518563ffffffff1660e01b81526004016117bd949392919061245c565b6020604051808303816000875af11580156117dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ac919061206c565b8051600090819081905b808210156119fe576000858381518110611826576118266124a7565b01602001517fff000000000000000000000000000000000000000000000000000000000000001690507f800000000000000000000000000000000000000000000000000000000000000081101561188957611882600184611fc4565b92506119eb565b7fe0000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156118de57611882600284611fc4565b7ff0000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216101561193357611882600384611fc4565b7ff8000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216101561198857611882600484611fc4565b7ffc000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610156119dd57611882600584611fc4565b6119e8600684611fc4565b92505b50826119f6816124d6565b93505061180a565b50909392505050565b600060208284031215611a1957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e3757600080fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114611a6d57600080fd5b919050565b600080600060608486031215611a8757600080fd5b611a9084611a49565b9250611a9e60208501611a49565b9150604084013590509250925092565b60008083601f840112611ac057600080fd5b50813567ffffffffffffffff811115611ad857600080fd5b602083019150836020828501011115611af057600080fd5b9250929050565b803563ffffffff81168114611a6d57600080fd5b803567ffffffffffffffff81168114611a6d57600080fd5b600080600080600060808688031215611b3b57600080fd5b853567ffffffffffffffff811115611b5257600080fd5b611b5e88828901611aae565b90965094505060208601359250611b7760408701611af7565b9150611b8560608701611b0b565b90509295509295909350565b60008083601f840112611ba357600080fd5b50813567ffffffffffffffff811115611bbb57600080fd5b6020830191508360208260051b8501011115611af057600080fd5b801515811461058a57600080fd5b60008060008060008060008060008060006101208c8e031215611c0657600080fd5b67ffffffffffffffff808d351115611c1d57600080fd5b611c2a8e8e358f01611aae565b909c509a50611c3b60208e01611a49565b995060408d0135985060608d01359750611c5760808e01611a49565b96508060a08e01351115611c6a57600080fd5b50611c7b8d60a08e01358e01611b91565b909550935060c08c0135611c8e81611bd6565b9250611c9c60e08d01611af7565b9150611cab6101008d01611b0b565b90509295989b509295989b9093969950565b600060208284031215611ccf57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611d2e57611d2e611cd6565b604052919050565b600067ffffffffffffffff821115611d5057611d50611cd6565b50601f01601f191660200190565b600082601f830112611d6f57600080fd5b8135611d82611d7d82611d36565b611d05565b818152846020838601011115611d9757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215611dc757600080fd5b823567ffffffffffffffff811115611dde57600080fd5b611dea85828601611d5e565b95602094909401359450505050565b600060208284031215611e0b57600080fd5b813567ffffffffffffffff811115611e2257600080fd5b610d3e84828501611d5e565b600080600060408486031215611e4357600080fd5b833567ffffffffffffffff811115611e5a57600080fd5b611e6686828701611aae565b909790965060209590950135949350505050565b6000806000806000806000806000806101208b8d031215611e9a57600080fd5b8a3567ffffffffffffffff80821115611eb257600080fd5b611ebe8e838f01611d5e565b9b50611ecc60208e01611a49565b9a5060408d0135995060608d01359850611ee860808e01611a49565b975060a08d0135915080821115611efe57600080fd5b50611f0b8d828e01611b91565b90965094505060c08b0135611f1f81611bd6565b9250611f2d60e08c01611af7565b9150611f3c6101008c01611b0b565b90509295989b9194979a5092959850565b600060208284031215611f5f57600080fd5b610e3782611a49565b600060208284031215611f7a57600080fd5b8151610e3781611bd6565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561053d5761053d611f95565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60c08152600061201660c08301898b611fd7565b905073ffffffffffffffffffffffffffffffffffffffff808816602084015286604084015280861660608401525063ffffffff8416608083015267ffffffffffffffff831660a083015298975050505050505050565b60006020828403121561207e57600080fd5b5051919050565b608081526000612099608083018789611fd7565b602083019590955250604081019290925260609091015292915050565b8181038181111561053d5761053d611f95565b60005b838110156120e45781810151838201526020016120cc565b50506000910152565b600081518084526121058160208601602086016120c9565b601f01601f19169290920160200192915050565b60608152600061212c60608301866120ed565b60208301949094525060400152919050565b60006040828403121561215057600080fd5b6040516040810181811067ffffffffffffffff8211171561217357612173611cd6565b604052825181526020928301519281019290925250919050565b81835260006020808501808196508560051b810191508460005b8781101561223057828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126121e657600080fd5b8701858101903567ffffffffffffffff81111561220257600080fd5b80360382131561221157600080fd5b61221c868284611fd7565b9a87019a95505050908401906001016121a7565b5091979650505050505050565b60006101208c835273ffffffffffffffffffffffffffffffffffffffff808d1660208501528b6040850152808b16606085015250806080840152612284818401898b61218d565b60a0840197909752505092151560c084015263ffffffff9190911660e083015267ffffffffffffffff16610100909101529695505050505050565b6060815260006122d3606083018688611fd7565b6020830194909452506040015292915050565b602081526000610e3760208301846120ed565b83815260406020820152600061231360408301848661218d565b95945050505050565b6000602080838503121561232f57600080fd5b825167ffffffffffffffff8082111561234757600080fd5b818501915085601f83011261235b57600080fd5b81518181111561236d5761236d611cd6565b8060051b61237c858201611d05565b918252838101850191858101908984111561239657600080fd5b86860192505b8383101561240e578251858111156123b45760008081fd5b8601603f81018b136123c65760008081fd5b8781015160406123d8611d7d83611d36565b8281528d828486010111156123ed5760008081fd5b6123fc838c83018487016120c9565b8552505050918601919086019061239c565b9998505050505050505050565b6000825161242d8184602087016120c9565b7f2e65746800000000000000000000000000000000000000000000000000000000920191825250600401919050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401528085166040840152506080606083015261249d60808301846120ed565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361250757612507611f95565b506001019056fea2646970667358221220d9fb3b87e91578f7a8a6d5440953ca3826801764d1dd460b7339ced1842a0af364736f6c63430008110033",
  "devdoc": {
    "details": "A registrar controller for registering and renewing names at fixed cost.",
    "kind": "dev",
    "methods": {
      "owner()": {
        "details": "Returns the address of the current owner."
      },
      "recoverFunds(address,address,uint256)": {
        "details": "The contract is Ownable and only the owner can call the recover function.",
        "params": {
          "_amount": "The amount of tokens to recover.",
          "_to": "The address to send the tokens to.",
          "_token": "The address of the ERC20 token to recover"
        }
      },
      "renounceOwnership()": {
        "details": "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."
      },
      "transferOwnership(address)": {
        "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
      }
    },
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "recoverFunds(address,address,uint256)": {
        "notice": "Recover ERC20 tokens sent to the contract by mistake."
      }
    },
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 545,
        "contract": "contracts/ethregistrar/ETHRegistrarController.sol:ETHRegistrarController",
        "label": "_owner",
        "offset": 0,
        "slot": "0",
        "type": "t_address"
      },
      {
        "astId": 9866,
        "contract": "contracts/ethregistrar/ETHRegistrarController.sol:ETHRegistrarController",
        "label": "commitments",
        "offset": 0,
        "slot": "1",
        "type": "t_mapping(t_bytes32,t_uint256)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_mapping(t_bytes32,t_uint256)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}