{
  "address": "0x8edc487D26F6c8Fa76e032066A3D4F87E273515d",
  "transactionHash": "0x9bc1943e89a850a05dcf1fab8cf5689495a1aada11c3ad964c4b327b5355dc29",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "contract DNSSEC",
          "name": "_dnssec",
          "type": "address"
        },
        {
          "internalType": "contract PublicSuffixList",
          "name": "_suffixes",
          "type": "address"
        },
        {
          "internalType": "contract ENS",
          "name": "_ens",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "node",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "bytes",
          "name": "dnsname",
          "type": "bytes"
        }
      ],
      "name": "Claim",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "oracle",
          "type": "address"
        }
      ],
      "name": "NewOracle",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "suffixes",
          "type": "address"
        }
      ],
      "name": "NewPublicSuffixList",
      "type": "event"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "proof",
          "type": "bytes"
        }
      ],
      "name": "claim",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "ens",
      "outputs": [
        {
          "internalType": "contract ENS",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "oracle",
      "outputs": [
        {
          "internalType": "contract DNSSEC",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        },
        {
          "components": [
            {
              "internalType": "bytes",
              "name": "rrset",
              "type": "bytes"
            },
            {
              "internalType": "bytes",
              "name": "sig",
              "type": "bytes"
            }
          ],
          "internalType": "struct DNSSEC.RRSetWithSignature[]",
          "name": "input",
          "type": "tuple[]"
        },
        {
          "internalType": "bytes",
          "name": "proof",
          "type": "bytes"
        }
      ],
      "name": "proveAndClaim",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        },
        {
          "components": [
            {
              "internalType": "bytes",
              "name": "rrset",
              "type": "bytes"
            },
            {
              "internalType": "bytes",
              "name": "sig",
              "type": "bytes"
            }
          ],
          "internalType": "struct DNSSEC.RRSetWithSignature[]",
          "name": "input",
          "type": "tuple[]"
        },
        {
          "internalType": "bytes",
          "name": "proof",
          "type": "bytes"
        },
        {
          "internalType": "address",
          "name": "resolver",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "addr",
          "type": "address"
        }
      ],
      "name": "proveAndClaimWithResolver",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract DNSSEC",
          "name": "_dnssec",
          "type": "address"
        }
      ],
      "name": "setOracle",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract PublicSuffixList",
          "name": "_suffixes",
          "type": "address"
        }
      ],
      "name": "setPublicSuffixList",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "suffixes",
      "outputs": [
        {
          "internalType": "contract PublicSuffixList",
          "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"
    }
  ],
  "transactionHash": "0x9bc1943e89a850a05dcf1fab8cf5689495a1aada11c3ad964c4b327b5355dc29",
  "receipt": {
    "to": null,
    "from": "0xa303ddC620aa7d1390BACcc8A495508B183fab59",
    "contractAddress": "0x8edc487D26F6c8Fa76e032066A3D4F87E273515d",
    "transactionIndex": 26,
    "gasUsed": "2157334",
    "logsBloom": "0x00000000000000100100000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000001000000000000000000000000000000000000008000000000000000000000000000000000000000008000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x0c53bb1267eac2453025659478ad87e921924599a276babad76f8f9ae49a70a6",
    "transactionHash": "0x9bc1943e89a850a05dcf1fab8cf5689495a1aada11c3ad964c4b327b5355dc29",
    "logs": [
      {
        "transactionIndex": 26,
        "blockNumber": 6470145,
        "transactionHash": "0x9bc1943e89a850a05dcf1fab8cf5689495a1aada11c3ad964c4b327b5355dc29",
        "address": "0x8edc487D26F6c8Fa76e032066A3D4F87E273515d",
        "topics": [
          "0xb3eacd0e351fafdfefdec84e1cd19679b38dbcd63ea7c2c24da17fd2bc3b3c0e"
        ],
        "data": "0x000000000000000000000000f427c4aded8b6dfde604865c1a7e953b160c26f0",
        "logIndex": 51,
        "blockHash": "0x0c53bb1267eac2453025659478ad87e921924599a276babad76f8f9ae49a70a6"
      },
      {
        "transactionIndex": 26,
        "blockNumber": 6470145,
        "transactionHash": "0x9bc1943e89a850a05dcf1fab8cf5689495a1aada11c3ad964c4b327b5355dc29",
        "address": "0x8edc487D26F6c8Fa76e032066A3D4F87E273515d",
        "topics": [
          "0x9176b7f47e4504df5e5516c99d90d82ac7cbd49cc77e7f22ba2ac2f2e3a3eba8"
        ],
        "data": "0x000000000000000000000000ed2e4cdc0280743b42f4415e3e8f7425a2d6b059",
        "logIndex": 52,
        "blockHash": "0x0c53bb1267eac2453025659478ad87e921924599a276babad76f8f9ae49a70a6"
      }
    ],
    "blockNumber": 6470145,
    "cumulativeGasUsed": "6636550",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0xF427c4AdED8B6dfde604865c1a7E953B160C26f0",
    "0xed2E4cDc0280743B42F4415E3e8F7425a2d6b059",
    "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
  ],
  "solcInputHash": "7948b60c3b601df824761a337a51d661",
  "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract DNSSEC\",\"name\":\"_dnssec\",\"type\":\"address\"},{\"internalType\":\"contract PublicSuffixList\",\"name\":\"_suffixes\",\"type\":\"address\"},{\"internalType\":\"contract ENS\",\"name\":\"_ens\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"dnsname\",\"type\":\"bytes\"}],\"name\":\"Claim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"NewOracle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"suffixes\",\"type\":\"address\"}],\"name\":\"NewPublicSuffixList\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ens\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract DNSSEC\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"rrset\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sig\",\"type\":\"bytes\"}],\"internalType\":\"struct DNSSEC.RRSetWithSignature[]\",\"name\":\"input\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"proveAndClaim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"rrset\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sig\",\"type\":\"bytes\"}],\"internalType\":\"struct DNSSEC.RRSetWithSignature[]\",\"name\":\"input\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"proof\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"proveAndClaimWithResolver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract DNSSEC\",\"name\":\"_dnssec\",\"type\":\"address\"}],\"name\":\"setOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract PublicSuffixList\",\"name\":\"_suffixes\",\"type\":\"address\"}],\"name\":\"setPublicSuffixList\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suffixes\",\"outputs\":[{\"internalType\":\"contract PublicSuffixList\",\"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\"}],\"devdoc\":{\"details\":\"An ENS registrar that allows the owner of a DNS name to claim the      corresponding name in ENS.\",\"kind\":\"dev\",\"methods\":{\"claim(bytes,bytes)\":{\"details\":\"Claims a name by proving ownership of its DNS equivalent.\",\"params\":{\"name\":\"The name to claim, in DNS wire format.\",\"proof\":\"A DNS RRSet proving ownership of the name. Must be verified        in the DNSSEC oracle before calling. This RRSET must contain a TXT        record for '_ens.' + name, with the value 'a=0x...'. Ownership of        the name will be transferred to the address specified in the TXT        record.\"}},\"proveAndClaim(bytes,(bytes,bytes)[],bytes)\":{\"details\":\"Submits proofs to the DNSSEC oracle, then claims a name using those proofs.\",\"params\":{\"input\":\"The data to be passed to the Oracle's `submitProofs` function. The last        proof must be the TXT record required by the registrar.\",\"name\":\"The name to claim, in DNS wire format.\",\"proof\":\"The proof record for the first element in input.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/dnsregistrar/DNSRegistrar.sol\":\"DNSRegistrar\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@ensdomains/buffer/contracts/Buffer.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\n/**\\n* @dev A library for working with mutable byte buffers in Solidity.\\n*\\n* Byte buffers are mutable and expandable, and provide a variety of primitives\\n* for writing to them. At any time you can fetch a bytes object containing the\\n* current contents of the buffer. The bytes object should not be stored between\\n* operations, as it may change due to resizing of the buffer.\\n*/\\nlibrary Buffer {\\n    /**\\n    * @dev Represents a mutable buffer. Buffers have a current value (buf) and\\n    *      a capacity. The capacity may be longer than the current value, in\\n    *      which case it can be extended without the need to allocate more memory.\\n    */\\n    struct buffer {\\n        bytes buf;\\n        uint capacity;\\n    }\\n\\n    /**\\n    * @dev Initializes a buffer with an initial capacity.\\n    * @param buf The buffer to initialize.\\n    * @param capacity The number of bytes of space to allocate the buffer.\\n    * @return The buffer, for chaining.\\n    */\\n    function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {\\n        if (capacity % 32 != 0) {\\n            capacity += 32 - (capacity % 32);\\n        }\\n        // Allocate space for the buffer data\\n        buf.capacity = capacity;\\n        assembly {\\n            let ptr := mload(0x40)\\n            mstore(buf, ptr)\\n            mstore(ptr, 0)\\n            mstore(0x40, add(32, add(ptr, capacity)))\\n        }\\n        return buf;\\n    }\\n\\n    /**\\n    * @dev Initializes a new buffer from an existing bytes object.\\n    *      Changes to the buffer may mutate the original value.\\n    * @param b The bytes object to initialize the buffer with.\\n    * @return A new buffer.\\n    */\\n    function fromBytes(bytes memory b) internal pure returns(buffer memory) {\\n        buffer memory buf;\\n        buf.buf = b;\\n        buf.capacity = b.length;\\n        return buf;\\n    }\\n\\n    function resize(buffer memory buf, uint capacity) private pure {\\n        bytes memory oldbuf = buf.buf;\\n        init(buf, capacity);\\n        append(buf, oldbuf);\\n    }\\n\\n    function max(uint a, uint b) private pure returns(uint) {\\n        if (a > b) {\\n            return a;\\n        }\\n        return b;\\n    }\\n\\n    /**\\n    * @dev Sets buffer length to 0.\\n    * @param buf The buffer to truncate.\\n    * @return The original buffer, for chaining..\\n    */\\n    function truncate(buffer memory buf) internal pure returns (buffer memory) {\\n        assembly {\\n            let bufptr := mload(buf)\\n            mstore(bufptr, 0)\\n        }\\n        return buf;\\n    }\\n\\n    /**\\n    * @dev Writes a byte string to a buffer. Resizes if doing so would exceed\\n    *      the capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param off The start offset to write to.\\n    * @param data The data to append.\\n    * @param len The number of bytes to copy.\\n    * @return The original buffer, for chaining.\\n    */\\n    function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) {\\n        require(len <= data.length);\\n\\n        if (off + len > buf.capacity) {\\n            resize(buf, max(buf.capacity, len + off) * 2);\\n        }\\n\\n        uint dest;\\n        uint src;\\n        assembly {\\n            // Memory address of the buffer data\\n            let bufptr := mload(buf)\\n            // Length of existing buffer data\\n            let buflen := mload(bufptr)\\n            // Start address = buffer address + offset + sizeof(buffer length)\\n            dest := add(add(bufptr, 32), off)\\n            // Update buffer length if we're extending it\\n            if gt(add(len, off), buflen) {\\n                mstore(bufptr, add(len, off))\\n            }\\n            src := add(data, 32)\\n        }\\n\\n        // Copy word-length chunks while possible\\n        for (; len >= 32; len -= 32) {\\n            assembly {\\n                mstore(dest, mload(src))\\n            }\\n            dest += 32;\\n            src += 32;\\n        }\\n\\n        // Copy remaining bytes\\n        unchecked {\\n            uint mask = (256 ** (32 - len)) - 1;\\n            assembly {\\n                let srcpart := and(mload(src), not(mask))\\n                let destpart := and(mload(dest), mask)\\n                mstore(dest, or(destpart, srcpart))\\n            }\\n        }\\n\\n        return buf;\\n    }\\n\\n    /**\\n    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed\\n    *      the capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param data The data to append.\\n    * @param len The number of bytes to copy.\\n    * @return The original buffer, for chaining.\\n    */\\n    function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) {\\n        return write(buf, buf.buf.length, data, len);\\n    }\\n\\n    /**\\n    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed\\n    *      the capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param data The data to append.\\n    * @return The original buffer, for chaining.\\n    */\\n    function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {\\n        return write(buf, buf.buf.length, data, data.length);\\n    }\\n\\n    /**\\n    * @dev Writes a byte to the buffer. Resizes if doing so would exceed the\\n    *      capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param off The offset to write the byte at.\\n    * @param data The data to append.\\n    * @return The original buffer, for chaining.\\n    */\\n    function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) {\\n        if (off >= buf.capacity) {\\n            resize(buf, buf.capacity * 2);\\n        }\\n\\n        assembly {\\n            // Memory address of the buffer data\\n            let bufptr := mload(buf)\\n            // Length of existing buffer data\\n            let buflen := mload(bufptr)\\n            // Address = buffer address + sizeof(buffer length) + off\\n            let dest := add(add(bufptr, off), 32)\\n            mstore8(dest, data)\\n            // Update buffer length if we extended it\\n            if eq(off, buflen) {\\n                mstore(bufptr, add(buflen, 1))\\n            }\\n        }\\n        return buf;\\n    }\\n\\n    /**\\n    * @dev Appends a byte to the buffer. Resizes if doing so would exceed the\\n    *      capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param data The data to append.\\n    * @return The original buffer, for chaining.\\n    */\\n    function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {\\n        return writeUint8(buf, buf.buf.length, data);\\n    }\\n\\n    /**\\n    * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would\\n    *      exceed the capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param off The offset to write at.\\n    * @param data The data to append.\\n    * @param len The number of bytes to write (left-aligned).\\n    * @return The original buffer, for chaining.\\n    */\\n    function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) {\\n        if (len + off > buf.capacity) {\\n            resize(buf, (len + off) * 2);\\n        }\\n\\n        unchecked {\\n            uint mask = (256 ** len) - 1;\\n            // Right-align data\\n            data = data >> (8 * (32 - len));\\n            assembly {\\n                // Memory address of the buffer data\\n                let bufptr := mload(buf)\\n                // Address = buffer address + sizeof(buffer length) + off + len\\n                let dest := add(add(bufptr, off), len)\\n                mstore(dest, or(and(mload(dest), not(mask)), data))\\n                // Update buffer length if we extended it\\n                if gt(add(off, len), mload(bufptr)) {\\n                    mstore(bufptr, add(off, len))\\n                }\\n            }\\n        }\\n        return buf;\\n    }\\n\\n    /**\\n    * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the\\n    *      capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param off The offset to write at.\\n    * @param data The data to append.\\n    * @return The original buffer, for chaining.\\n    */\\n    function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) {\\n        return write(buf, off, bytes32(data), 20);\\n    }\\n\\n    /**\\n    * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed\\n    *      the capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param data The data to append.\\n    * @return The original buffer, for chhaining.\\n    */\\n    function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {\\n        return write(buf, buf.buf.length, bytes32(data), 20);\\n    }\\n\\n    /**\\n    * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed\\n    *      the capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param data The data to append.\\n    * @return The original buffer, for chaining.\\n    */\\n    function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {\\n        return write(buf, buf.buf.length, data, 32);\\n    }\\n\\n    /**\\n    * @dev Writes an integer to the buffer. Resizes if doing so would exceed\\n    *      the capacity of the buffer.\\n    * @param buf The buffer to append to.\\n    * @param off The offset to write at.\\n    * @param data The data to append.\\n    * @param len The number of bytes to write (right-aligned).\\n    * @return The original buffer, for chaining.\\n    */\\n    function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) {\\n        if (len + off > buf.capacity) {\\n            resize(buf, (len + off) * 2);\\n        }\\n\\n        uint mask = (256 ** len) - 1;\\n        assembly {\\n            // Memory address of the buffer data\\n            let bufptr := mload(buf)\\n            // Address = buffer address + off + sizeof(buffer length) + len\\n            let dest := add(add(bufptr, off), len)\\n            mstore(dest, or(and(mload(dest), not(mask)), data))\\n            // Update buffer length if we extended it\\n            if gt(add(off, len), mload(bufptr)) {\\n                mstore(bufptr, add(off, len))\\n            }\\n        }\\n        return buf;\\n    }\\n\\n    /**\\n     * @dev Appends a byte to the end of the buffer. Resizes if doing so would\\n     * exceed the capacity of the buffer.\\n     * @param buf The buffer to append to.\\n     * @param data The data to append.\\n     * @return The original buffer.\\n     */\\n    function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) {\\n        return writeInt(buf, buf.buf.length, data, len);\\n    }\\n}\\n\",\"keccak256\":\"0x18e42be1a3e4f7b4442d7ab0b524af5e09163503439954faf0ab3792cce91caa\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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        _setOwner(_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        _setOwner(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        _setOwner(newOwner);\\n    }\\n\\n    function _setOwner(address newOwner) private {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/dnsregistrar/DNSClaimChecker.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"../dnssec-oracle/DNSSEC.sol\\\";\\nimport \\\"../dnssec-oracle/BytesUtils.sol\\\";\\nimport \\\"../dnssec-oracle/RRUtils.sol\\\";\\nimport \\\"@ensdomains/buffer/contracts/Buffer.sol\\\";\\n\\nlibrary DNSClaimChecker {\\n\\n    using BytesUtils for bytes;\\n    using RRUtils for *;\\n    using Buffer for Buffer.buffer;\\n\\n    uint16 constant CLASS_INET = 1;\\n    uint16 constant TYPE_TXT = 16;\\n\\n    function getOwnerAddress(DNSSEC oracle, bytes memory name, bytes memory proof)\\n        internal\\n        view\\n        returns (address, bool)\\n    {\\n        // Add \\\"_ens.\\\" to the front of the name.\\n        Buffer.buffer memory buf;\\n        buf.init(name.length + 5);\\n        buf.append(\\\"\\\\x04_ens\\\");\\n        buf.append(name);\\n        bytes20 hash;\\n        uint32 expiration;\\n        // Check the provided TXT record has been validated by the oracle\\n        (, expiration, hash) = oracle.rrdata(TYPE_TXT, buf.buf);\\n        if (hash == bytes20(0) && proof.length == 0) return (address(0x0), false);\\n\\n        require(hash == bytes20(keccak256(proof)));\\n\\n        for (RRUtils.RRIterator memory iter = proof.iterateRRs(0); !iter.done(); iter.next()) {\\n            require(RRUtils.serialNumberGte(expiration + iter.ttl, uint32(block.timestamp)), \\\"DNS record is stale; refresh or delete it before proceeding.\\\");\\n\\n            bool found;\\n            address addr;\\n            (addr, found) = parseRR(proof, iter.rdataOffset);\\n            if (found) {\\n                return (addr, true);\\n            }\\n        }\\n\\n        return (address(0x0), false);\\n    }\\n\\n    function parseRR(bytes memory rdata, uint idx) internal pure returns (address, bool) {\\n        while (idx < rdata.length) {\\n            uint len = rdata.readUint8(idx); idx += 1;\\n\\n            bool found;\\n            address addr;\\n            (addr, found) = parseString(rdata, idx, len);\\n\\n            if (found) return (addr, true);\\n            idx += len;\\n        }\\n\\n        return (address(0x0), false);\\n    }\\n\\n    function parseString(bytes memory str, uint idx, uint len) internal pure returns (address, bool) {\\n        // TODO: More robust parsing that handles whitespace and multiple key/value pairs\\n        if (str.readUint32(idx) != 0x613d3078) return (address(0x0), false); // 0x613d3078 == 'a=0x'\\n        if (len < 44) return (address(0x0), false);\\n        return hexToAddress(str, idx + 4);\\n    }\\n\\n    function hexToAddress(bytes memory str, uint idx) internal pure returns (address, bool) {\\n        if (str.length - idx < 40) return (address(0x0), false);\\n        uint ret = 0;\\n        for (uint i = idx; i < idx + 40; i++) {\\n            ret <<= 4;\\n            uint x = str.readUint8(i);\\n            if (x >= 48 && x < 58) {\\n                ret |= x - 48;\\n            } else if (x >= 65 && x < 71) {\\n                ret |= x - 55;\\n            } else if (x >= 97 && x < 103) {\\n                ret |= x - 87;\\n            } else {\\n                return (address(0x0), false);\\n            }\\n        }\\n        return (address(uint160(ret)), true);\\n    }\\n}\\n\",\"keccak256\":\"0xbbae9477060a4e16d01432400029b85d278a7186dad7139d0f24381906cf63db\"},\"contracts/dnsregistrar/DNSRegistrar.sol\":{\"content\":\"pragma solidity ^0.8.4;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../dnssec-oracle/BytesUtils.sol\\\";\\nimport \\\"../dnssec-oracle/DNSSEC.sol\\\";\\nimport \\\"../registry/ENSRegistry.sol\\\";\\nimport \\\"../root/Root.sol\\\";\\nimport \\\"./DNSClaimChecker.sol\\\";\\nimport \\\"./PublicSuffixList.sol\\\";\\nimport \\\"../resolvers/profiles/AddrResolver.sol\\\";\\n\\ninterface IDNSRegistrar {\\n    function claim(bytes memory name, bytes memory proof) external;\\n    function proveAndClaim(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof) external;\\n    function proveAndClaimWithResolver(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof, address resolver, address addr) external;\\n}\\n\\n/**\\n * @dev An ENS registrar that allows the owner of a DNS name to claim the\\n *      corresponding name in ENS.\\n */\\ncontract DNSRegistrar is IDNSRegistrar {\\n    using BytesUtils for bytes;\\n\\n    DNSSEC public oracle;\\n    ENS public ens;\\n    PublicSuffixList public suffixes;\\n\\n    bytes4 constant private INTERFACE_META_ID = bytes4(keccak256(\\\"supportsInterface(bytes4)\\\"));\\n\\n    event Claim(bytes32 indexed node, address indexed owner, bytes dnsname);\\n    event NewOracle(address oracle);\\n    event NewPublicSuffixList(address suffixes);\\n\\n    constructor(DNSSEC _dnssec, PublicSuffixList _suffixes, ENS _ens) {\\n        oracle = _dnssec;\\n        emit NewOracle(address(oracle));\\n        suffixes = _suffixes;\\n        emit NewPublicSuffixList(address(suffixes));\\n        ens = _ens;\\n    }\\n\\n    /**\\n     * @dev This contract's owner-only functions can be invoked by the owner of the ENS root.\\n     */\\n    modifier onlyOwner {\\n        Root root = Root(ens.owner(bytes32(0)));\\n        address owner = root.owner();\\n        require(msg.sender == owner);\\n        _;\\n    }\\n\\n    function setOracle(DNSSEC _dnssec) public onlyOwner {\\n        oracle = _dnssec;\\n        emit NewOracle(address(oracle));\\n    }\\n\\n    function setPublicSuffixList(PublicSuffixList _suffixes) public onlyOwner {\\n        suffixes = _suffixes;\\n        emit NewPublicSuffixList(address(suffixes));\\n    }\\n\\n    /**\\n     * @dev Claims a name by proving ownership of its DNS equivalent.\\n     * @param name The name to claim, in DNS wire format.\\n     * @param proof A DNS RRSet proving ownership of the name. Must be verified\\n     *        in the DNSSEC oracle before calling. This RRSET must contain a TXT\\n     *        record for '_ens.' + name, with the value 'a=0x...'. Ownership of\\n     *        the name will be transferred to the address specified in the TXT\\n     *        record.\\n     */\\n    function claim(bytes memory name, bytes memory proof) public override {\\n        (bytes32 rootNode, bytes32 labelHash, address addr) = _claim(name, proof);\\n        ens.setSubnodeOwner(rootNode, labelHash, addr);\\n    }\\n\\n    /**\\n     * @dev Submits proofs to the DNSSEC oracle, then claims a name using those proofs.\\n     * @param name The name to claim, in DNS wire format.\\n     * @param input The data to be passed to the Oracle's `submitProofs` function. The last\\n     *        proof must be the TXT record required by the registrar.\\n     * @param proof The proof record for the first element in input.\\n     */\\n    function proveAndClaim(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof) public override {\\n        proof = oracle.submitRRSets(input, proof);\\n        claim(name, proof);\\n    }\\n\\n    function proveAndClaimWithResolver(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof, address resolver, address addr) public override {\\n        proof = oracle.submitRRSets(input, proof);\\n        (bytes32 rootNode, bytes32 labelHash, address owner) = _claim(name, proof);\\n        require(msg.sender == owner, \\\"Only owner can call proveAndClaimWithResolver\\\");\\n        if(addr != address(0)) {\\n            require(resolver != address(0), \\\"Cannot set addr if resolver is not set\\\");\\n            // Set ourselves as the owner so we can set a record on the resolver\\n            ens.setSubnodeRecord(rootNode, labelHash, address(this), resolver, 0);\\n            bytes32 node = keccak256(abi.encodePacked(rootNode, labelHash));\\n            // Set the resolver record\\n            AddrResolver(resolver).setAddr(node, addr);\\n            // Transfer the record to the owner\\n            ens.setOwner(node, owner);\\n        } else {\\n            ens.setSubnodeRecord(rootNode, labelHash, owner, resolver, 0);\\n        }\\n    }\\n\\n    function supportsInterface(bytes4 interfaceID) external pure returns (bool) {\\n        return interfaceID == INTERFACE_META_ID ||\\n               interfaceID == type(IDNSRegistrar).interfaceId;\\n    }\\n\\n    function _claim(bytes memory name, bytes memory proof) internal returns(bytes32 rootNode, bytes32 labelHash, address addr) {\\n        // Get the first label\\n        uint labelLen = name.readUint8(0);\\n        labelHash = name.keccak(1, labelLen);\\n\\n        // Parent name must be in the public suffix list.\\n        bytes memory parentName = name.substring(labelLen + 1, name.length - labelLen - 1);\\n        require(suffixes.isPublicSuffix(parentName), \\\"Parent name must be a public suffix\\\");\\n\\n        // Make sure the parent name is enabled\\n        rootNode = enableNode(parentName, 0);\\n\\n        (addr,) = DNSClaimChecker.getOwnerAddress(oracle, name, proof);\\n\\n        emit Claim(keccak256(abi.encodePacked(rootNode, labelHash)), addr, name);\\n    }\\n\\n    function enableNode(bytes memory domain, uint offset) internal returns(bytes32 node) {\\n        uint len = domain.readUint8(offset);\\n        if(len == 0) {\\n            return bytes32(0);\\n        }\\n\\n        bytes32 parentNode = enableNode(domain, offset + len + 1);\\n        bytes32 label = domain.keccak(offset + 1, len);\\n        node = keccak256(abi.encodePacked(parentNode, label));\\n        address owner = ens.owner(node);\\n        require(owner == address(0) || owner == address(this), \\\"Cannot enable a name owned by someone else\\\");\\n        if(owner != address(this)) {\\n            if(parentNode == bytes32(0)) {\\n                Root root = Root(ens.owner(bytes32(0)));\\n                root.setSubnodeOwner(label, address(this));\\n            } else {\\n                ens.setSubnodeOwner(parentNode, label, address(this));\\n            }\\n        }\\n        return node;\\n    }\\n}\\n\",\"keccak256\":\"0x0781f008efeefa1ff7a9517ed94d69fe160c399c7cd6388a79e26d7f0e4e6001\"},\"contracts/dnsregistrar/PublicSuffixList.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\ninterface PublicSuffixList {\\n    function isPublicSuffix(bytes calldata name) external view returns(bool);\\n}\\n\",\"keccak256\":\"0x8e593c73f54e07a54074ed3b6bc8e976d06211f923051c9793bcb9c10114854d\"},\"contracts/dnssec-oracle/BytesUtils.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nlibrary BytesUtils {\\n    /*\\n    * @dev Returns the keccak-256 hash of a byte range.\\n    * @param self The byte string to hash.\\n    * @param offset The position to start hashing at.\\n    * @param len The number of bytes to hash.\\n    * @return The hash of the byte range.\\n    */\\n    function keccak(bytes memory self, uint offset, uint len) internal pure returns (bytes32 ret) {\\n        require(offset + len <= self.length);\\n        assembly {\\n            ret := keccak256(add(add(self, 32), offset), len)\\n        }\\n    }\\n\\n\\n    /*\\n    * @dev Returns a positive number if `other` comes lexicographically after\\n    *      `self`, a negative number if it comes before, or zero if the\\n    *      contents of the two bytes are equal.\\n    * @param self The first bytes to compare.\\n    * @param other The second bytes to compare.\\n    * @return The result of the comparison.\\n    */\\n    function compare(bytes memory self, bytes memory other) internal pure returns (int) {\\n        return compare(self, 0, self.length, other, 0, other.length);\\n    }\\n\\n    /*\\n    * @dev Returns a positive number if `other` comes lexicographically after\\n    *      `self`, a negative number if it comes before, or zero if the\\n    *      contents of the two bytes are equal. Comparison is done per-rune,\\n    *      on unicode codepoints.\\n    * @param self The first bytes to compare.\\n    * @param offset The offset of self.\\n    * @param len    The length of self.\\n    * @param other The second bytes to compare.\\n    * @param otheroffset The offset of the other string.\\n    * @param otherlen    The length of the other string.\\n    * @return The result of the comparison.\\n    */\\n    function compare(bytes memory self, uint offset, uint len, bytes memory other, uint otheroffset, uint otherlen) internal pure returns (int) {\\n        uint shortest = len;\\n        if (otherlen < len)\\n        shortest = otherlen;\\n\\n        uint selfptr;\\n        uint otherptr;\\n\\n        assembly {\\n            selfptr := add(self, add(offset, 32))\\n            otherptr := add(other, add(otheroffset, 32))\\n        }\\n        for (uint idx = 0; idx < shortest; idx += 32) {\\n            uint a;\\n            uint b;\\n            assembly {\\n                a := mload(selfptr)\\n                b := mload(otherptr)\\n            }\\n            if (a != b) {\\n                // Mask out irrelevant bytes and check again\\n                uint mask;\\n                if (shortest > 32) {\\n                    mask = type(uint256).max;\\n                } else {\\n                    mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);\\n                }\\n                int diff = int(a & mask) - int(b & mask);\\n                if (diff != 0)\\n                return diff;\\n            }\\n            selfptr += 32;\\n            otherptr += 32;\\n        }\\n\\n        return int(len) - int(otherlen);\\n    }\\n\\n    /*\\n    * @dev Returns true if the two byte ranges are equal.\\n    * @param self The first byte range to compare.\\n    * @param offset The offset into the first byte range.\\n    * @param other The second byte range to compare.\\n    * @param otherOffset The offset into the second byte range.\\n    * @param len The number of bytes to compare\\n    * @return True if the byte ranges are equal, false otherwise.\\n    */\\n    function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset, uint len) internal pure returns (bool) {\\n        return keccak(self, offset, len) == keccak(other, otherOffset, len);\\n    }\\n\\n    /*\\n    * @dev Returns true if the two byte ranges are equal with offsets.\\n    * @param self The first byte range to compare.\\n    * @param offset The offset into the first byte range.\\n    * @param other The second byte range to compare.\\n    * @param otherOffset The offset into the second byte range.\\n    * @return True if the byte ranges are equal, false otherwise.\\n    */\\n    function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset) internal pure returns (bool) {\\n        return keccak(self, offset, self.length - offset) == keccak(other, otherOffset, other.length - otherOffset);\\n    }\\n\\n    /*\\n    * @dev Compares a range of 'self' to all of 'other' and returns True iff\\n    *      they are equal.\\n    * @param self The first byte range to compare.\\n    * @param offset The offset into the first byte range.\\n    * @param other The second byte range to compare.\\n    * @return True if the byte ranges are equal, false otherwise.\\n    */\\n    function equals(bytes memory self, uint offset, bytes memory other) internal pure returns (bool) {\\n        return self.length >= offset + other.length && equals(self, offset, other, 0, other.length);\\n    }\\n\\n    /*\\n    * @dev Returns true if the two byte ranges are equal.\\n    * @param self The first byte range to compare.\\n    * @param other The second byte range to compare.\\n    * @return True if the byte ranges are equal, false otherwise.\\n    */\\n    function equals(bytes memory self, bytes memory other) internal pure returns(bool) {\\n        return self.length == other.length && equals(self, 0, other, 0, self.length);\\n    }\\n\\n    /*\\n    * @dev Returns the 8-bit number at the specified index of self.\\n    * @param self The byte string.\\n    * @param idx The index into the bytes\\n    * @return The specified 8 bits of the string, interpreted as an integer.\\n    */\\n    function readUint8(bytes memory self, uint idx) internal pure returns (uint8 ret) {\\n        return uint8(self[idx]);\\n    }\\n\\n    /*\\n    * @dev Returns the 16-bit number at the specified index of self.\\n    * @param self The byte string.\\n    * @param idx The index into the bytes\\n    * @return The specified 16 bits of the string, interpreted as an integer.\\n    */\\n    function readUint16(bytes memory self, uint idx) internal pure returns (uint16 ret) {\\n        require(idx + 2 <= self.length);\\n        assembly {\\n            ret := and(mload(add(add(self, 2), idx)), 0xFFFF)\\n        }\\n    }\\n\\n    /*\\n    * @dev Returns the 32-bit number at the specified index of self.\\n    * @param self The byte string.\\n    * @param idx The index into the bytes\\n    * @return The specified 32 bits of the string, interpreted as an integer.\\n    */\\n    function readUint32(bytes memory self, uint idx) internal pure returns (uint32 ret) {\\n        require(idx + 4 <= self.length);\\n        assembly {\\n            ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF)\\n        }\\n    }\\n\\n    /*\\n    * @dev Returns the 32 byte value at the specified index of self.\\n    * @param self The byte string.\\n    * @param idx The index into the bytes\\n    * @return The specified 32 bytes of the string.\\n    */\\n    function readBytes32(bytes memory self, uint idx) internal pure returns (bytes32 ret) {\\n        require(idx + 32 <= self.length);\\n        assembly {\\n            ret := mload(add(add(self, 32), idx))\\n        }\\n    }\\n\\n    /*\\n    * @dev Returns the 32 byte value at the specified index of self.\\n    * @param self The byte string.\\n    * @param idx The index into the bytes\\n    * @return The specified 32 bytes of the string.\\n    */\\n    function readBytes20(bytes memory self, uint idx) internal pure returns (bytes20 ret) {\\n        require(idx + 20 <= self.length);\\n        assembly {\\n            ret := and(mload(add(add(self, 32), idx)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000)\\n        }\\n    }\\n\\n    /*\\n    * @dev Returns the n byte value at the specified index of self.\\n    * @param self The byte string.\\n    * @param idx The index into the bytes.\\n    * @param len The number of bytes.\\n    * @return The specified 32 bytes of the string.\\n    */\\n    function readBytesN(bytes memory self, uint idx, uint len) internal pure returns (bytes32 ret) {\\n        require(len <= 32);\\n        require(idx + len <= self.length);\\n        assembly {\\n            let mask := not(sub(exp(256, sub(32, len)), 1))\\n            ret := and(mload(add(add(self, 32), idx)),  mask)\\n        }\\n    }\\n\\n    function memcpy(uint dest, uint src, uint len) private pure {\\n        // Copy word-length chunks while possible\\n        for (; len >= 32; len -= 32) {\\n            assembly {\\n                mstore(dest, mload(src))\\n            }\\n            dest += 32;\\n            src += 32;\\n        }\\n\\n        // Copy remaining bytes\\n        unchecked {\\n            uint mask = (256 ** (32 - len)) - 1;\\n            assembly {\\n                let srcpart := and(mload(src), not(mask))\\n                let destpart := and(mload(dest), mask)\\n                mstore(dest, or(destpart, srcpart))\\n            }\\n        }\\n    }\\n\\n    /*\\n    * @dev Copies a substring into a new byte string.\\n    * @param self The byte string to copy from.\\n    * @param offset The offset to start copying at.\\n    * @param len The number of bytes to copy.\\n    */\\n    function substring(bytes memory self, uint offset, uint len) internal pure returns(bytes memory) {\\n        require(offset + len <= self.length);\\n\\n        bytes memory ret = new bytes(len);\\n        uint dest;\\n        uint src;\\n\\n        assembly {\\n            dest := add(ret, 32)\\n            src := add(add(self, 32), offset)\\n        }\\n        memcpy(dest, src, len);\\n\\n        return ret;\\n    }\\n\\n    // Maps characters from 0x30 to 0x7A to their base32 values.\\n    // 0xFF represents invalid characters in that range.\\n    bytes constant base32HexTable = hex'00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F';\\n\\n    /**\\n     * @dev Decodes unpadded base32 data of up to one word in length.\\n     * @param self The data to decode.\\n     * @param off Offset into the string to start at.\\n     * @param len Number of characters to decode.\\n     * @return The decoded data, left aligned.\\n     */\\n    function base32HexDecodeWord(bytes memory self, uint off, uint len) internal pure returns(bytes32) {\\n        require(len <= 52);\\n\\n        uint ret = 0;\\n        uint8 decoded;\\n        for(uint i = 0; i < len; i++) {\\n            bytes1 char = self[off + i];\\n            require(char >= 0x30 && char <= 0x7A);\\n            decoded = uint8(base32HexTable[uint(uint8(char)) - 0x30]);\\n            require(decoded <= 0x20);\\n            if(i == len - 1) {\\n                break;\\n            }\\n            ret = (ret << 5) | decoded;\\n        }\\n\\n        uint bitlen = len * 5;\\n        if(len % 8 == 0) {\\n            // Multiple of 8 characters, no padding\\n            ret = (ret << 5) | decoded;\\n        } else if(len % 8 == 2) {\\n            // Two extra characters - 1 byte\\n            ret = (ret << 3) | (decoded >> 2);\\n            bitlen -= 2;\\n        } else if(len % 8 == 4) {\\n            // Four extra characters - 2 bytes\\n            ret = (ret << 1) | (decoded >> 4);\\n            bitlen -= 4;\\n        } else if(len % 8 == 5) {\\n            // Five extra characters - 3 bytes\\n            ret = (ret << 4) | (decoded >> 1);\\n            bitlen -= 1;\\n        } else if(len % 8 == 7) {\\n            // Seven extra characters - 4 bytes\\n            ret = (ret << 2) | (decoded >> 3);\\n            bitlen -= 3;\\n        } else {\\n            revert();\\n        }\\n\\n        return bytes32(ret << (256 - bitlen));\\n    }\\n}\",\"keccak256\":\"0x83315df2e54c74451577c70da2c267c3459802b08b9aeec6516302eee70f796e\"},\"contracts/dnssec-oracle/DNSSEC.sol\":{\"content\":\"pragma solidity ^0.8.4;\\npragma experimental ABIEncoderV2;\\n\\nabstract contract DNSSEC {\\n\\n    bytes public anchors;\\n\\n    struct RRSetWithSignature {\\n        bytes rrset;\\n        bytes sig;\\n    }\\n\\n    event AlgorithmUpdated(uint8 id, address addr);\\n    event DigestUpdated(uint8 id, address addr);\\n    event NSEC3DigestUpdated(uint8 id, address addr);\\n    event RRSetUpdated(bytes name, bytes rrset);\\n\\n    function submitRRSets(RRSetWithSignature[] memory input, bytes calldata proof) public virtual returns (bytes memory);\\n    function submitRRSet(RRSetWithSignature calldata input, bytes calldata proof) public virtual returns (bytes memory);\\n    function deleteRRSet(uint16 deleteType, bytes calldata deleteName, RRSetWithSignature calldata nsec, bytes calldata proof) public virtual;\\n    function deleteRRSetNSEC3(uint16 deleteType, bytes memory deleteName, RRSetWithSignature memory closestEncloser, RRSetWithSignature memory nextClosest, bytes memory dnskey) public virtual;\\n    function rrdata(uint16 dnstype, bytes calldata name) external virtual view returns (uint32, uint32, bytes20);\\n}\\n\",\"keccak256\":\"0x5b8d2391f66e878e09aa88a97fe8ea5b26604a0c0ad9247feb6124db9817f6c1\"},\"contracts/dnssec-oracle/RRUtils.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"./BytesUtils.sol\\\";\\nimport \\\"@ensdomains/buffer/contracts/Buffer.sol\\\";\\n\\n/**\\n* @dev RRUtils is a library that provides utilities for parsing DNS resource records.\\n*/\\nlibrary RRUtils {\\n    using BytesUtils for *;\\n    using Buffer for *;\\n\\n    /**\\n    * @dev Returns the number of bytes in the DNS name at 'offset' in 'self'.\\n    * @param self The byte array to read a name from.\\n    * @param offset The offset to start reading at.\\n    * @return The length of the DNS name at 'offset', in bytes.\\n    */\\n    function nameLength(bytes memory self, uint offset) internal pure returns(uint) {\\n        uint idx = offset;\\n        while (true) {\\n            assert(idx < self.length);\\n            uint labelLen = self.readUint8(idx);\\n            idx += labelLen + 1;\\n            if (labelLen == 0) {\\n                break;\\n            }\\n        }\\n        return idx - offset;\\n    }\\n\\n    /**\\n    * @dev Returns a DNS format name at the specified offset of self.\\n    * @param self The byte array to read a name from.\\n    * @param offset The offset to start reading at.\\n    * @return ret The name.\\n    */\\n    function readName(bytes memory self, uint offset) internal pure returns(bytes memory ret) {\\n        uint len = nameLength(self, offset);\\n        return self.substring(offset, len);\\n    }\\n\\n    /**\\n    * @dev Returns the number of labels in the DNS name at 'offset' in 'self'.\\n    * @param self The byte array to read a name from.\\n    * @param offset The offset to start reading at.\\n    * @return The number of labels in the DNS name at 'offset', in bytes.\\n    */\\n    function labelCount(bytes memory self, uint offset) internal pure returns(uint) {\\n        uint count = 0;\\n        while (true) {\\n            assert(offset < self.length);\\n            uint labelLen = self.readUint8(offset);\\n            offset += labelLen + 1;\\n            if (labelLen == 0) {\\n                break;\\n            }\\n            count += 1;\\n        }\\n        return count;\\n    }\\n\\n    uint constant RRSIG_TYPE = 0;\\n    uint constant RRSIG_ALGORITHM = 2;\\n    uint constant RRSIG_LABELS = 3;\\n    uint constant RRSIG_TTL = 4;\\n    uint constant RRSIG_EXPIRATION = 8;\\n    uint constant RRSIG_INCEPTION = 12;\\n    uint constant RRSIG_KEY_TAG = 16;\\n    uint constant RRSIG_SIGNER_NAME = 18;\\n\\n    struct SignedSet {\\n        uint16 typeCovered;\\n        uint8 algorithm;\\n        uint8 labels;\\n        uint32 ttl;\\n        uint32 expiration;\\n        uint32 inception;\\n        uint16 keytag;\\n        bytes signerName;\\n        bytes data;\\n        bytes name;\\n    }\\n\\n    function readSignedSet(bytes memory data) internal pure returns(SignedSet memory self) {\\n        self.typeCovered = data.readUint16(RRSIG_TYPE);\\n        self.algorithm = data.readUint8(RRSIG_ALGORITHM);\\n        self.labels = data.readUint8(RRSIG_LABELS);\\n        self.ttl = data.readUint32(RRSIG_TTL);\\n        self.expiration = data.readUint32(RRSIG_EXPIRATION);\\n        self.inception = data.readUint32(RRSIG_INCEPTION);\\n        self.keytag = data.readUint16(RRSIG_KEY_TAG);\\n        self.signerName = readName(data, RRSIG_SIGNER_NAME);\\n        self.data = data.substring(RRSIG_SIGNER_NAME + self.signerName.length, data.length - RRSIG_SIGNER_NAME - self.signerName.length);\\n    }\\n\\n    function rrs(SignedSet memory rrset) internal pure returns(RRIterator memory) {\\n        return iterateRRs(rrset.data, 0);\\n    }\\n\\n    /**\\n    * @dev An iterator over resource records.\\n    */\\n    struct RRIterator {\\n        bytes data;\\n        uint offset;\\n        uint16 dnstype;\\n        uint16 class;\\n        uint32 ttl;\\n        uint rdataOffset;\\n        uint nextOffset;\\n    }\\n\\n    /**\\n    * @dev Begins iterating over resource records.\\n    * @param self The byte string to read from.\\n    * @param offset The offset to start reading at.\\n    * @return ret An iterator object.\\n    */\\n    function iterateRRs(bytes memory self, uint offset) internal pure returns (RRIterator memory ret) {\\n        ret.data = self;\\n        ret.nextOffset = offset;\\n        next(ret);\\n    }\\n\\n    /**\\n    * @dev Returns true iff there are more RRs to iterate.\\n    * @param iter The iterator to check.\\n    * @return True iff the iterator has finished.\\n    */\\n    function done(RRIterator memory iter) internal pure returns(bool) {\\n        return iter.offset >= iter.data.length;\\n    }\\n\\n    /**\\n    * @dev Moves the iterator to the next resource record.\\n    * @param iter The iterator to advance.\\n    */\\n    function next(RRIterator memory iter) internal pure {\\n        iter.offset = iter.nextOffset;\\n        if (iter.offset >= iter.data.length) {\\n            return;\\n        }\\n\\n        // Skip the name\\n        uint off = iter.offset + nameLength(iter.data, iter.offset);\\n\\n        // Read type, class, and ttl\\n        iter.dnstype = iter.data.readUint16(off);\\n        off += 2;\\n        iter.class = iter.data.readUint16(off);\\n        off += 2;\\n        iter.ttl = iter.data.readUint32(off);\\n        off += 4;\\n\\n        // Read the rdata\\n        uint rdataLength = iter.data.readUint16(off);\\n        off += 2;\\n        iter.rdataOffset = off;\\n        iter.nextOffset = off + rdataLength;\\n    }\\n\\n    /**\\n    * @dev Returns the name of the current record.\\n    * @param iter The iterator.\\n    * @return A new bytes object containing the owner name from the RR.\\n    */\\n    function name(RRIterator memory iter) internal pure returns(bytes memory) {\\n        return iter.data.substring(iter.offset, nameLength(iter.data, iter.offset));\\n    }\\n\\n    /**\\n    * @dev Returns the rdata portion of the current record.\\n    * @param iter The iterator.\\n    * @return A new bytes object containing the RR's RDATA.\\n    */\\n    function rdata(RRIterator memory iter) internal pure returns(bytes memory) {\\n        return iter.data.substring(iter.rdataOffset, iter.nextOffset - iter.rdataOffset);\\n    }\\n\\n    uint constant DNSKEY_FLAGS = 0;\\n    uint constant DNSKEY_PROTOCOL = 2;\\n    uint constant DNSKEY_ALGORITHM = 3;\\n    uint constant DNSKEY_PUBKEY = 4;\\n\\n    struct DNSKEY {\\n        uint16 flags;\\n        uint8 protocol;\\n        uint8 algorithm;\\n        bytes publicKey;\\n    }\\n\\n    function readDNSKEY(bytes memory data, uint offset, uint length) internal pure returns(DNSKEY memory self) {\\n        self.flags = data.readUint16(offset + DNSKEY_FLAGS);\\n        self.protocol = data.readUint8(offset + DNSKEY_PROTOCOL);\\n        self.algorithm = data.readUint8(offset + DNSKEY_ALGORITHM);\\n        self.publicKey = data.substring(offset + DNSKEY_PUBKEY, length - DNSKEY_PUBKEY);\\n    } \\n\\n    uint constant DS_KEY_TAG = 0;\\n    uint constant DS_ALGORITHM = 2;\\n    uint constant DS_DIGEST_TYPE = 3;\\n    uint constant DS_DIGEST = 4;\\n\\n    struct DS {\\n        uint16 keytag;\\n        uint8 algorithm;\\n        uint8 digestType;\\n        bytes digest;\\n    }\\n\\n    function readDS(bytes memory data, uint offset, uint length) internal pure returns(DS memory self) {\\n        self.keytag = data.readUint16(offset + DS_KEY_TAG);\\n        self.algorithm = data.readUint8(offset + DS_ALGORITHM);\\n        self.digestType = data.readUint8(offset + DS_DIGEST_TYPE);\\n        self.digest = data.substring(offset + DS_DIGEST, length - DS_DIGEST);\\n    }\\n\\n    struct NSEC3 {\\n        uint8 hashAlgorithm;\\n        uint8 flags;\\n        uint16 iterations;\\n        bytes salt;\\n        bytes32 nextHashedOwnerName;\\n        bytes typeBitmap;\\n    }\\n\\n    uint constant NSEC3_HASH_ALGORITHM = 0;\\n    uint constant NSEC3_FLAGS = 1;\\n    uint constant NSEC3_ITERATIONS = 2;\\n    uint constant NSEC3_SALT_LENGTH = 4;\\n    uint constant NSEC3_SALT = 5;\\n\\n    function readNSEC3(bytes memory data, uint offset, uint length) internal pure returns(NSEC3 memory self) {\\n        uint end = offset + length;\\n        self.hashAlgorithm = data.readUint8(offset + NSEC3_HASH_ALGORITHM);\\n        self.flags = data.readUint8(offset + NSEC3_FLAGS);\\n        self.iterations = data.readUint16(offset + NSEC3_ITERATIONS);\\n        uint8 saltLength = data.readUint8(offset + NSEC3_SALT_LENGTH);\\n        offset = offset + NSEC3_SALT;\\n        self.salt = data.substring(offset, saltLength);\\n        offset += saltLength;\\n        uint8 nextLength = data.readUint8(offset);\\n        require(nextLength <= 32);\\n        offset += 1;\\n        self.nextHashedOwnerName = data.readBytesN(offset, nextLength);\\n        offset += nextLength;\\n        self.typeBitmap = data.substring(offset, end - offset);\\n    }\\n\\n    function checkTypeBitmap(NSEC3 memory self, uint16 rrtype) internal pure returns(bool) {\\n        return checkTypeBitmap(self.typeBitmap, 0, rrtype);\\n    }\\n\\n    /**\\n    * @dev Checks if a given RR type exists in a type bitmap.\\n    * @param bitmap The byte string to read the type bitmap from.\\n    * @param offset The offset to start reading at.\\n    * @param rrtype The RR type to check for.\\n    * @return True if the type is found in the bitmap, false otherwise.\\n    */\\n    function checkTypeBitmap(bytes memory bitmap, uint offset, uint16 rrtype) internal pure returns (bool) {\\n        uint8 typeWindow = uint8(rrtype >> 8);\\n        uint8 windowByte = uint8((rrtype & 0xff) / 8);\\n        uint8 windowBitmask = uint8(uint8(1) << (uint8(7) - uint8(rrtype & 0x7)));\\n        for (uint off = offset; off < bitmap.length;) {\\n            uint8 window = bitmap.readUint8(off);\\n            uint8 len = bitmap.readUint8(off + 1);\\n            if (typeWindow < window) {\\n                // We've gone past our window; it's not here.\\n                return false;\\n            } else if (typeWindow == window) {\\n                // Check this type bitmap\\n                if (len <= windowByte) {\\n                    // Our type is past the end of the bitmap\\n                    return false;\\n                }\\n                return (bitmap.readUint8(off + windowByte + 2) & windowBitmask) != 0;\\n            } else {\\n                // Skip this type bitmap\\n                off += len + 2;\\n            }\\n        }\\n\\n        return false;\\n    }\\n\\n    function compareNames(bytes memory self, bytes memory other) internal pure returns (int) {\\n        if (self.equals(other)) {\\n            return 0;\\n        }\\n\\n        uint off;\\n        uint otheroff;\\n        uint prevoff;\\n        uint otherprevoff;\\n        uint counts = labelCount(self, 0);\\n        uint othercounts = labelCount(other, 0);\\n\\n        // Keep removing labels from the front of the name until both names are equal length\\n        while (counts > othercounts) {\\n            prevoff = off;\\n            off = progress(self, off);\\n            counts--;\\n        }\\n\\n        while (othercounts > counts) {\\n            otherprevoff = otheroff;\\n            otheroff = progress(other, otheroff);\\n            othercounts--;\\n        }\\n\\n        // Compare the last nonequal labels to each other\\n        while (counts > 0 && !self.equals(off, other, otheroff)) {\\n            prevoff = off;\\n            off = progress(self, off);\\n            otherprevoff = otheroff;\\n            otheroff = progress(other, otheroff);\\n            counts -= 1;\\n        }\\n\\n        if (off == 0) {\\n            return -1;\\n        }\\n        if(otheroff == 0) {\\n            return 1;\\n        }\\n\\n        return self.compare(prevoff + 1, self.readUint8(prevoff), other, otherprevoff + 1, other.readUint8(otherprevoff));\\n    }\\n\\n    /**\\n     * @dev Compares two serial numbers using RFC1982 serial number math.\\n     */\\n    function serialNumberGte(uint32 i1, uint32 i2) internal pure returns(bool) {\\n        return int32(i1) - int32(i2) >= 0;\\n    }\\n\\n    function progress(bytes memory body, uint off) internal pure returns(uint) {\\n        return off + 1 + body.readUint8(off);\\n    }\\n\\n    /**\\n     * @dev Computes the keytag for a chunk of data.\\n     * @param data The data to compute a keytag for.\\n     * @return The computed key tag.\\n     */\\n    function computeKeytag(bytes memory data) internal pure returns (uint16) {\\n        /* This function probably deserves some explanation.\\n         * The DNSSEC keytag function is a checksum that relies on summing up individual bytes\\n         * from the input string, with some mild bitshifting. Here's a Naive solidity implementation:\\n         *\\n         *     function computeKeytag(bytes memory data) internal pure returns (uint16) {\\n         *         uint ac;\\n         *         for (uint i = 0; i < data.length; i++) {\\n         *             ac += i & 1 == 0 ? uint16(data.readUint8(i)) << 8 : data.readUint8(i);\\n         *         }\\n         *         return uint16(ac + (ac >> 16));\\n         *     }\\n         *\\n         * The EVM, with its 256 bit words, is exceedingly inefficient at doing byte-by-byte operations;\\n         * the code above, on reasonable length inputs, consumes over 100k gas. But we can make the EVM's\\n         * large words work in our favour.\\n         *\\n         * The code below works by treating the input as a series of 256 bit words. It first masks out\\n         * even and odd bytes from each input word, adding them to two separate accumulators `ac1` and `ac2`.\\n         * The bytes are separated by empty bytes, so as long as no individual sum exceeds 2^16-1, we're\\n         * effectively summing 16 different numbers with each EVM ADD opcode.\\n         *\\n         * Once it's added up all the inputs, it has to add all the 16 bit values in `ac1` and `ac2` together.\\n         * It does this using the same trick - mask out every other value, shift to align them, add them together.\\n         * After the first addition on both accumulators, there's enough room to add the two accumulators together,\\n         * and the remaining sums can be done just on ac1.\\n         */\\n        unchecked {\\n            require(data.length <= 8192, \\\"Long keys not permitted\\\");\\n            uint ac1;\\n            uint ac2;\\n            for(uint i = 0; i < data.length + 31; i += 32) {\\n                uint word;\\n                assembly {\\n                    word := mload(add(add(data, 32), i))\\n                }\\n                if(i + 32 > data.length) {\\n                    uint unused = 256 - (data.length - i) * 8;\\n                    word = (word >> unused) << unused;\\n                }\\n                ac1 += (word & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8;\\n                ac2 += (word & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF);\\n            }\\n            ac1 = (ac1 & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF)\\n                + ((ac1 & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16);\\n            ac2 = (ac2 & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF)\\n                + ((ac2 & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16);\\n            ac1 = (ac1 << 8) + ac2;\\n            ac1 = (ac1 & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF)\\n                + ((ac1 & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32);\\n            ac1 = (ac1 & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF)\\n                + ((ac1 & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64);\\n            ac1 = (ac1 & 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\\n                + (ac1 >> 128);\\n            ac1 += (ac1 >> 16) & 0xFFFF;\\n            return uint16(ac1);\\n        }\\n    }\\n}\",\"keccak256\":\"0x811642c86c539d645ef99a15fa1bf0eb4ce963cf1a618ef2a6f34d27a5e34030\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n\\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(address indexed owner, address indexed operator, bool approved);\\n\\n    function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual;\\n    function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual;\\n    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external virtual returns(bytes32);\\n    function setResolver(bytes32 node, address resolver) external virtual;\\n    function setOwner(bytes32 node, address owner) external virtual;\\n    function setTTL(bytes32 node, uint64 ttl) external virtual;\\n    function setApprovalForAll(address operator, bool approved) external virtual;\\n    function owner(bytes32 node) external virtual view returns (address);\\n    function resolver(bytes32 node) external virtual view returns (address);\\n    function ttl(bytes32 node) external virtual view returns (uint64);\\n    function recordExists(bytes32 node) external virtual view returns (bool);\\n    function isApprovedForAll(address owner, address operator) external virtual view returns (bool);\\n}\\n\",\"keccak256\":\"0x942ef29bd7c0f62228aeb91879ddd1ba101f52a2162970d3e48adffa498f4483\"},\"contracts/registry/ENSRegistry.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\nimport \\\"./ENS.sol\\\";\\n\\n/**\\n * The ENS registry contract.\\n */\\ncontract ENSRegistry is ENS {\\n\\n    struct Record {\\n        address owner;\\n        address resolver;\\n        uint64 ttl;\\n    }\\n\\n    mapping (bytes32 => Record) records;\\n    mapping (address => mapping(address => bool)) operators;\\n\\n    // Permits modifications only by the owner of the specified node.\\n    modifier authorised(bytes32 node) {\\n        address owner = records[node].owner;\\n        require(owner == msg.sender || operators[owner][msg.sender]);\\n        _;\\n    }\\n\\n    /**\\n     * @dev Constructs a new ENS registrar.\\n     */\\n    constructor() public {\\n        records[0x0].owner = msg.sender;\\n    }\\n\\n    /**\\n     * @dev Sets the record for a node.\\n     * @param node The node to update.\\n     * @param owner The address of the new owner.\\n     * @param resolver The address of the resolver.\\n     * @param ttl The TTL in seconds.\\n     */\\n    function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual override {\\n        setOwner(node, owner);\\n        _setResolverAndTTL(node, resolver, ttl);\\n    }\\n\\n    /**\\n     * @dev Sets the record for a subnode.\\n     * @param node The parent node.\\n     * @param label The hash of the label specifying the subnode.\\n     * @param owner The address of the new owner.\\n     * @param resolver The address of the resolver.\\n     * @param ttl The TTL in seconds.\\n     */\\n    function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual override {\\n        bytes32 subnode = setSubnodeOwner(node, label, owner);\\n        _setResolverAndTTL(subnode, resolver, ttl);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of a node to a new address. May only be called by the current owner of the node.\\n     * @param node The node to transfer ownership of.\\n     * @param owner The address of the new owner.\\n     */\\n    function setOwner(bytes32 node, address owner) public virtual override authorised(node) {\\n        _setOwner(node, owner);\\n        emit Transfer(node, owner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of a subnode keccak256(node, label) to a new address. May only be called by the owner of the parent node.\\n     * @param node The parent node.\\n     * @param label The hash of the label specifying the subnode.\\n     * @param owner The address of the new owner.\\n     */\\n    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public virtual override authorised(node) returns(bytes32) {\\n        bytes32 subnode = keccak256(abi.encodePacked(node, label));\\n        _setOwner(subnode, owner);\\n        emit NewOwner(node, label, owner);\\n        return subnode;\\n    }\\n\\n    /**\\n     * @dev Sets the resolver address for the specified node.\\n     * @param node The node to update.\\n     * @param resolver The address of the resolver.\\n     */\\n    function setResolver(bytes32 node, address resolver) public virtual override authorised(node) {\\n        emit NewResolver(node, resolver);\\n        records[node].resolver = resolver;\\n    }\\n\\n    /**\\n     * @dev Sets the TTL for the specified node.\\n     * @param node The node to update.\\n     * @param ttl The TTL in seconds.\\n     */\\n    function setTTL(bytes32 node, uint64 ttl) public virtual override authorised(node) {\\n        emit NewTTL(node, ttl);\\n        records[node].ttl = ttl;\\n    }\\n\\n    /**\\n     * @dev Enable or disable approval for a third party (\\\"operator\\\") to manage\\n     *  all of `msg.sender`'s ENS records. Emits the ApprovalForAll event.\\n     * @param operator Address to add to the set of authorized operators.\\n     * @param approved True if the operator is approved, false to revoke approval.\\n     */\\n    function setApprovalForAll(address operator, bool approved) external virtual override {\\n        operators[msg.sender][operator] = approved;\\n        emit ApprovalForAll(msg.sender, operator, approved);\\n    }\\n\\n    /**\\n     * @dev Returns the address that owns the specified node.\\n     * @param node The specified node.\\n     * @return address of the owner.\\n     */\\n    function owner(bytes32 node) public virtual override view returns (address) {\\n        address addr = records[node].owner;\\n        if (addr == address(this)) {\\n            return address(0x0);\\n        }\\n\\n        return addr;\\n    }\\n\\n    /**\\n     * @dev Returns the address of the resolver for the specified node.\\n     * @param node The specified node.\\n     * @return address of the resolver.\\n     */\\n    function resolver(bytes32 node) public virtual override view returns (address) {\\n        return records[node].resolver;\\n    }\\n\\n    /**\\n     * @dev Returns the TTL of a node, and any records associated with it.\\n     * @param node The specified node.\\n     * @return ttl of the node.\\n     */\\n    function ttl(bytes32 node) public virtual override view returns (uint64) {\\n        return records[node].ttl;\\n    }\\n\\n    /**\\n     * @dev Returns whether a record has been imported to the registry.\\n     * @param node The specified node.\\n     * @return Bool if record exists\\n     */\\n    function recordExists(bytes32 node) public virtual override view returns (bool) {\\n        return records[node].owner != address(0x0);\\n    }\\n\\n    /**\\n     * @dev Query if an address is an authorized operator for another address.\\n     * @param owner The address that owns the records.\\n     * @param operator The address that acts on behalf of the owner.\\n     * @return True if `operator` is an approved operator for `owner`, false otherwise.\\n     */\\n    function isApprovedForAll(address owner, address operator) external virtual override view returns (bool) {\\n        return operators[owner][operator];\\n    }\\n\\n    function _setOwner(bytes32 node, address owner) internal virtual {\\n        records[node].owner = owner;\\n    }\\n\\n    function _setResolverAndTTL(bytes32 node, address resolver, uint64 ttl) internal {\\n        if(resolver != records[node].resolver) {\\n            records[node].resolver = resolver;\\n            emit NewResolver(node, resolver);\\n        }\\n\\n        if(ttl != records[node].ttl) {\\n            records[node].ttl = ttl;\\n            emit NewTTL(node, ttl);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xf025a2fa3fcf89a3db7064e85e9b618707a39cb47c9c1bfedaec5313b118a1c6\"},\"contracts/resolvers/ISupportsInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface ISupportsInterface {\\n    function supportsInterface(bytes4 interfaceID) external pure returns(bool);\\n}\",\"keccak256\":\"0x4960422af4a3d38a2c440c656104465cba7dea0231cb7ae4a489a85dd65f645f\",\"license\":\"MIT\"},\"contracts/resolvers/ResolverBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"./SupportsInterface.sol\\\";\\n\\nabstract contract ResolverBase is SupportsInterface {\\n    function isAuthorised(bytes32 node) internal virtual view returns(bool);\\n\\n    modifier authorised(bytes32 node) {\\n        require(isAuthorised(node));\\n        _;\\n    }\\n}\\n\",\"keccak256\":\"0xee4e3e99b515bdb2fc231c81fc6ff35cf09c3b57e9aaef538bfbb32f7c59248c\",\"license\":\"MIT\"},\"contracts/resolvers/SupportsInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport \\\"./ISupportsInterface.sol\\\";\\n\\nabstract contract SupportsInterface is ISupportsInterface {\\n    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {\\n        return interfaceID == type(ISupportsInterface).interfaceId;\\n    }\\n}\\n\",\"keccak256\":\"0xcd27206ee8f8bd520d5441294f6438dde98f6933eb8801ee59a0155b8a8cde1b\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/AddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"../ResolverBase.sol\\\";\\nimport \\\"./IAddrResolver.sol\\\";\\nimport \\\"./IAddressResolver.sol\\\";\\n\\nabstract contract AddrResolver is IAddrResolver, IAddressResolver, ResolverBase {\\n    uint constant private COIN_TYPE_ETH = 60;\\n\\n    mapping(bytes32=>mapping(uint=>bytes)) _addresses;\\n\\n    /**\\n     * Sets the address 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     * @param a The address to set.\\n     */\\n    function setAddr(bytes32 node, address a) virtual external authorised(node) {\\n        setAddr(node, COIN_TYPE_ETH, addressToBytes(a));\\n    }\\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) virtual override public view returns (address payable) {\\n        bytes memory a = addr(node, COIN_TYPE_ETH);\\n        if(a.length == 0) {\\n            return payable(0);\\n        }\\n        return bytesToAddress(a);\\n    }\\n\\n    function setAddr(bytes32 node, uint coinType, bytes memory a) virtual public authorised(node) {\\n        emit AddressChanged(node, coinType, a);\\n        if(coinType == COIN_TYPE_ETH) {\\n            emit AddrChanged(node, bytesToAddress(a));\\n        }\\n        _addresses[node][coinType] = a;\\n    }\\n\\n    function addr(bytes32 node, uint coinType) virtual override public view returns(bytes memory) {\\n        return _addresses[node][coinType];\\n    }\\n\\n    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {\\n        return interfaceID == type(IAddrResolver).interfaceId || interfaceID == type(IAddressResolver).interfaceId || super.supportsInterface(interfaceID);\\n    }\\n\\n    function bytesToAddress(bytes memory b) internal pure returns(address payable a) {\\n        require(b.length == 20);\\n        assembly {\\n            a := div(mload(add(b, 32)), exp(256, 12))\\n        }\\n    }\\n\\n    function addressToBytes(address a) internal pure returns(bytes memory b) {\\n        b = new bytes(20);\\n        assembly {\\n            mstore(add(b, 32), mul(a, exp(256, 12)))\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x356ed43442c7598b7489e1d1fef89f7b226e53c55e5cd319274b1fb7b7a81355\",\"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(bytes32 indexed node, uint coinType, bytes newAddress);\\n\\n    function addr(bytes32 node, uint coinType) external view returns(bytes memory);\\n}\\n\",\"keccak256\":\"0x20717682fa28eb1755a3b6ade738c8e0239c1cc393579058d4c3ffaca238c04b\",\"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\":\"0x0c364a5b65b6fff279adbe1fd6498c488feabeec781599cd60a5844e80ee7d88\"},\"contracts/root/Root.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"../registry/ENS.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./Controllable.sol\\\";\\n\\ncontract Root is Ownable, Controllable {\\n    bytes32 private constant ROOT_NODE = bytes32(0);\\n\\n    bytes4 private constant INTERFACE_META_ID =\\n        bytes4(keccak256(\\\"supportsInterface(bytes4)\\\"));\\n\\n    event TLDLocked(bytes32 indexed label);\\n\\n    ENS public ens;\\n    mapping(bytes32 => bool) public locked;\\n\\n    constructor(ENS _ens) public {\\n        ens = _ens;\\n    }\\n\\n    function setSubnodeOwner(bytes32 label, address owner)\\n        external\\n        onlyController\\n    {\\n        require(!locked[label]);\\n        ens.setSubnodeOwner(ROOT_NODE, label, owner);\\n    }\\n\\n    function setResolver(address resolver) external onlyOwner {\\n        ens.setResolver(ROOT_NODE, resolver);\\n    }\\n\\n    function lock(bytes32 label) external onlyOwner {\\n        emit TLDLocked(label);\\n        locked[label] = true;\\n    }\\n\\n    function supportsInterface(bytes4 interfaceID)\\n        external\\n        pure\\n        returns (bool)\\n    {\\n        return interfaceID == INTERFACE_META_ID;\\n    }\\n}\\n\",\"keccak256\":\"0xf6fed46bbdc8a425d112c473a649045148b2e0404647c97590d2a3e2798c9fe3\"}},\"version\":1}",
  "bytecode": "0x60806040523480156200001157600080fd5b5060405162002669380380620026698339810160408190526200003491620000ff565b600080546001600160a01b0319166001600160a01b0385169081179091556040519081527fb3eacd0e351fafdfefdec84e1cd19679b38dbcd63ea7c2c24da17fd2bc3b3c0e9060200160405180910390a1600280546001600160a01b0319166001600160a01b0384169081179091556040519081527f9176b7f47e4504df5e5516c99d90d82ac7cbd49cc77e7f22ba2ac2f2e3a3eba89060200160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055506200016b9050565b60008060006060848603121562000114578283fd5b8351620001218162000152565b6020850151909350620001348162000152565b6040850151909250620001478162000152565b809150509250925092565b6001600160a01b03811681146200016857600080fd5b50565b6124ee806200017b6000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80633f15457f116100765780637dc0d1d01161005b5780637dc0d1d0146101705780638bbedf7514610190578063be27b22c146101a357600080fd5b80633f15457f1461013d5780637adbf9731461015d57600080fd5b806301ffc9a7146100a85780631ecfc411146100d0578063224199c2146100e557806330349ebe146100f8575b600080fd5b6100bb6100b6366004611e6a565b6101b6565b60405190151581526020015b60405180910390f35b6100e36100de3660046120ae565b61024f565b005b6100e36100f3366004611fa1565b610414565b6002546101189073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c7565b6001546101189073ffffffffffffffffffffffffffffffffffffffff1681565b6100e361016b3660046120ae565b6108e1565b6000546101189073ffffffffffffffffffffffffffffffffffffffff1681565b6100e361019e366004611f1d565b610a9d565b6100e36101b136600461204d565b610b5c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061024957507fffffffff0000000000000000000000000000000000000000000000000000000082167f17d8f49b00000000000000000000000000000000000000000000000000000000145b92915050565b6001546040517f02571be30000000000000000000000000000000000000000000000000000000081526000600482018190529173ffffffffffffffffffffffffffffffffffffffff16906302571be39060240160206040518083038186803b1580156102ba57600080fd5b505afa1580156102ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f29190611e16565b905060008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561033c57600080fd5b505afa158015610350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103749190611e16565b90503373ffffffffffffffffffffffffffffffffffffffff82161461039857600080fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85169081179091556040519081527f9176b7f47e4504df5e5516c99d90d82ac7cbd49cc77e7f22ba2ac2f2e3a3eba8906020015b60405180910390a1505050565b6000546040517f435cc16200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063435cc1629061046c9087908790600401612160565b600060405180830381600087803b15801561048657600080fd5b505af115801561049a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104c29190810190611eaa565b925060008060006104d38887610c30565b919450925090503373ffffffffffffffffffffffffffffffffffffffff821614610584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f6e6c79206f776e65722063616e2063616c6c2070726f7665416e64436c616960448201527f6d576974685265736f6c7665720000000000000000000000000000000000000060648201526084015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8416156108345773ffffffffffffffffffffffffffffffffffffffff8516610643576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f43616e6e6f74207365742061646472206966207265736f6c766572206973206e60448201527f6f74207365740000000000000000000000000000000000000000000000000000606482015260840161057b565b6001546040517f5ef2c7f0000000000000000000000000000000000000000000000000000000008152600481018590526024810184905230604482015273ffffffffffffffffffffffffffffffffffffffff87811660648301526000608483015290911690635ef2c7f09060a401600060405180830381600087803b1580156106cb57600080fd5b505af11580156106df573d6000803e3d6000fd5b5050505060008383604051602001610701929190918252602082015260400190565b60408051808303601f190181529082905280516020909101207fd5fa2b000000000000000000000000000000000000000000000000000000000082526004820181905273ffffffffffffffffffffffffffffffffffffffff878116602484015290925087169063d5fa2b0090604401600060405180830381600087803b15801561078a57600080fd5b505af115801561079e573d6000803e3d6000fd5b50506001546040517f5b0fc9c30000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff86811660248301529091169250635b0fc9c39150604401600060405180830381600087803b15801561081657600080fd5b505af115801561082a573d6000803e3d6000fd5b50505050506108d7565b6001546040517f5ef2c7f0000000000000000000000000000000000000000000000000000000008152600481018590526024810184905273ffffffffffffffffffffffffffffffffffffffff838116604483015287811660648301526000608483015290911690635ef2c7f09060a401600060405180830381600087803b1580156108be57600080fd5b505af11580156108d2573d6000803e3d6000fd5b505050505b5050505050505050565b6001546040517f02571be30000000000000000000000000000000000000000000000000000000081526000600482018190529173ffffffffffffffffffffffffffffffffffffffff16906302571be39060240160206040518083038186803b15801561094c57600080fd5b505afa158015610960573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109849190611e16565b905060008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109ce57600080fd5b505afa1580156109e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a069190611e16565b90503373ffffffffffffffffffffffffffffffffffffffff821614610a2a57600080fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85169081179091556040519081527fb3eacd0e351fafdfefdec84e1cd19679b38dbcd63ea7c2c24da17fd2bc3b3c0e90602001610407565b6000546040517f435cc16200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063435cc16290610af59085908590600401612160565b600060405180830381600087803b158015610b0f57600080fd5b505af1158015610b23573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4b9190810190611eaa565b9050610b578382610b5c565b505050565b6000806000610b6b8585610c30565b6001546040517f06ab5923000000000000000000000000000000000000000000000000000000008152600481018590526024810184905273ffffffffffffffffffffffffffffffffffffffff808416604483015294975092955090935091909116906306ab592390606401602060405180830381600087803b158015610bf057600080fd5b505af1158015610c04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c289190611e52565b505050505050565b6000808080610c3f8682610e6e565b60ff169050610c5086600183610eb9565b92506000610c83610c6283600161229f565b6001848a51610c719190612380565b610c7b9190612380565b899190610edd565b6002546040517f4f89059e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634f89059e90610cda908490600401612216565b60206040518083038186803b158015610cf257600080fd5b505afa158015610d06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2a9190611e32565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f506172656e74206e616d65206d7573742062652061207075626c69632073756660448201527f6669780000000000000000000000000000000000000000000000000000000000606482015260840161057b565b610dc1816000610f86565b600054909550610de89073ffffffffffffffffffffffffffffffffffffffff16888861138d565b50604080516020810188905290810186905290935073ffffffffffffffffffffffffffffffffffffffff841690606001604051602081830303815290604052805190602001207fa2e66ce20e6fb2c4f61339c364ad79f15160cf5307230c8bc4d628adbca2ba3989604051610e5d9190612216565b60405180910390a350509250925092565b6000828281518110610ea9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b016020015160f81c905092915050565b8251600090610ec8838561229f565b1115610ed357600080fd5b5091016020012090565b8251606090610eec838561229f565b1115610ef757600080fd5b60008267ffffffffffffffff811115610f39577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015610f63576020820181803683370190505b50905060208082019086860101610f7b82828761164c565b509095945050505050565b600080610f938484610e6e565b60ff16905080610fa7575060009050610249565b6000610fc785610fb7848761229f565b610fc290600161229f565b610f86565b90506000610fe1610fd986600161229f565b879085610eb9565b604080516020810185905290810182905290915060600160408051808303601f190181529082905280516020909101206001547f02571be30000000000000000000000000000000000000000000000000000000083526004830182905290955060009173ffffffffffffffffffffffffffffffffffffffff909116906302571be39060240160206040518083038186803b15801561107e57600080fd5b505afa158015611092573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b69190611e16565b905073ffffffffffffffffffffffffffffffffffffffff811615806110f0575073ffffffffffffffffffffffffffffffffffffffff811630145b61117c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f43616e6e6f7420656e61626c652061206e616d65206f776e656420627920736f60448201527f6d656f6e6520656c736500000000000000000000000000000000000000000000606482015260840161057b565b73ffffffffffffffffffffffffffffffffffffffff8116301461138357826112d0576001546040517f02571be30000000000000000000000000000000000000000000000000000000081526000600482018190529173ffffffffffffffffffffffffffffffffffffffff16906302571be39060240160206040518083038186803b15801561120957600080fd5b505afa15801561121d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112419190611e16565b6040517f8cb8ecec0000000000000000000000000000000000000000000000000000000081526004810185905230602482015290915073ffffffffffffffffffffffffffffffffffffffff821690638cb8ecec90604401600060405180830381600087803b1580156112b257600080fd5b505af11580156112c6573d6000803e3d6000fd5b5050505050611383565b6001546040517f06ab5923000000000000000000000000000000000000000000000000000000008152600481018590526024810184905230604482015273ffffffffffffffffffffffffffffffffffffffff909116906306ab592390606401602060405180830381600087803b15801561134957600080fd5b505af115801561135d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113819190611e52565b505b5050505092915050565b6000806113ad604051806040016040528060608152602001600081525090565b6113c5855160056113be919061229f565b82906116c0565b5060408051808201909152600581527f045f656e730000000000000000000000000000000000000000000000000000006020820152611405908290611725565b506114108186611725565b5080516040517f087991bc000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff8a169163087991bc9161146b91601091600401612229565b60606040518083038186803b15801561148357600080fd5b505afa158015611497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114bb91906120ca565b93509150507fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082161580156114ef57508551155b156115035760008094509450505050611644565b855160208701207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083811691161461153a57600080fd5b60006115468782611753565b90505b805151602082015110156116385761157081608001518361156a91906122b7565b426117b4565b6115fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f444e53207265636f7264206973207374616c653b2072656672657368206f722060448201527f64656c657465206974206265666f72652070726f63656564696e672e00000000606482015260840161057b565b60008061160d898460a001516117cd565b92509050811561162857965060019550611644945050505050565b505061163381611840565b611549565b50600080945094505050505b935093915050565b60208110611684578151835261166360208461229f565b925061167060208361229f565b915061167d602082612380565b905061164c565b905182516020929092036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169116179052565b6040805180820190915260608152600060208201526116e06020836123fc565b15611708576116f06020836123fc565b6116fb906020612380565b611705908361229f565b91505b506020828101829052604080518085526000815290920101905290565b60408051808201909152606081526000602082015261174c83846000015151848551611928565b9392505050565b6117a16040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b82815260c0810182905261024981611840565b6000806117c1838561231c565b60030b12159392505050565b6000805b83518310156118325760006117e68585610e6e565b60ff1690506117f660018561229f565b9350600080611806878785611a30565b92509050811561181e57935060019250611839915050565b611828838761229f565b95505050506117d1565b5060009050805b9250929050565b60c081015160208201819052815151116118575750565b600061186b82600001518360200151611a8c565b826020015161187a919061229f565b82519091506118899082611b12565b61ffff16604083015261189d60028261229f565b82519091506118ac9082611b12565b61ffff1660608301526118c060028261229f565b82519091506118cf9082611b3a565b63ffffffff1660808301526118e560048261229f565b82519091506000906118f79083611b12565b61ffff16905061190860028361229f565b60a08401819052915061191b818361229f565b60c0909301929092525050565b604080518082019091526060815260006020820152825182111561194b57600080fd5b602085015161195a838661229f565b111561198d5761198d8561197d87602001518786611978919061229f565b611b64565b6119889060026122df565b611b7b565b6000808651805187602083010193508088870111156119ac5787860182525b505050602084015b602084106119ec57805182526119cb60208361229f565b91506119d860208261229f565b90506119e5602085612380565b93506119b4565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208690036101000a019081169019919091161790525083949350505050565b600080611a3d8585611b3a565b63ffffffff1663613d307814611a5857506000905080611644565b602c831015611a6c57506000905080611644565b611a8085611a7b86600461229f565b611b98565b91509150935093915050565b6000815b83518110611ac7577f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000611ad38583610e6e565b60ff169050611ae381600161229f565b611aed908361229f565b915080611afa5750611b00565b50611a90565b611b0a8382612380565b949350505050565b8151600090611b2283600261229f565b1115611b2d57600080fd5b50016002015161ffff1690565b8151600090611b4a83600461229f565b1115611b5557600080fd5b50016004015163ffffffff1690565b600081831115611b75575081610249565b50919050565b8151611b8783836116c0565b50611b928382611725565b50505050565b6000806028838551611baa9190612380565b1015611bbb57506000905080611839565b6000835b611bca85602861229f565b811015611c775760049190911b906000611be48783610e6e565b60ff16905060308110158015611bfa5750603a81105b15611c1357611c0a603082612380565b83179250611c64565b60418110158015611c245750604781105b15611c3457611c0a603782612380565b60618110158015611c455750606781105b15611c5557611c0a605782612380565b60008094509450505050611839565b5080611c6f816123c3565b915050611bbf565b50946001945092505050565b600082601f830112611c93578081fd5b8135602067ffffffffffffffff80831115611cb057611cb0612464565b8260051b611cbf838201612246565b8481528381019087850183890186018a1015611cd9578788fd5b8793505b86841015611d1657803585811115611cf3578889fd5b611d018b88838d0101611d74565b84525060019390930192918501918501611cdd565b5098975050505050505050565b600082601f830112611d33578081fd5b8135611d46611d4182612277565b612246565b818152846020838601011115611d5a578283fd5b816020850160208301379081016020019190915292915050565b600060408284031215611d85578081fd5b6040516040810167ffffffffffffffff8282108183111715611da957611da9612464565b816040528293508435915080821115611dc157600080fd5b611dcd86838701611d23565b83526020850135915080821115611de357600080fd5b50611df085828601611d23565b6020830152505092915050565b805163ffffffff81168114611e1157600080fd5b919050565b600060208284031215611e27578081fd5b815161174c81612493565b600060208284031215611e43578081fd5b8151801515811461174c578182fd5b600060208284031215611e63578081fd5b5051919050565b600060208284031215611e7b578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461174c578182fd5b600060208284031215611ebb578081fd5b815167ffffffffffffffff811115611ed1578182fd5b8201601f81018413611ee1578182fd5b8051611eef611d4182612277565b818152856020838501011115611f03578384fd5b611f14826020830160208601612397565b95945050505050565b600080600060608486031215611f31578182fd5b833567ffffffffffffffff80821115611f48578384fd5b611f5487838801611d23565b94506020860135915080821115611f69578384fd5b611f7587838801611c83565b93506040860135915080821115611f8a578283fd5b50611f9786828701611d23565b9150509250925092565b600080600080600060a08688031215611fb8578081fd5b853567ffffffffffffffff80821115611fcf578283fd5b611fdb89838a01611d23565b96506020880135915080821115611ff0578283fd5b611ffc89838a01611c83565b95506040880135915080821115612011578283fd5b5061201e88828901611d23565b935050606086013561202f81612493565b9150608086013561203f81612493565b809150509295509295909350565b6000806040838503121561205f578182fd5b823567ffffffffffffffff80821115612076578384fd5b61208286838701611d23565b93506020850135915080821115612097578283fd5b506120a485828601611d23565b9150509250929050565b6000602082840312156120bf578081fd5b813561174c81612493565b6000806000606084860312156120de578081fd5b6120e784611dfd565b92506120f560208501611dfd565b915060408401517fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081168114612129578182fd5b809150509250925092565b6000815180845261214c816020860160208601612397565b601f01601f19169290920160200192915050565b6000604080830181845280865180835260608601915060608160051b87010192506020808901865b838110156121f6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0898703018552815180518888526121ca89890182612134565b91850151888303898701529190506121e28183612134565b975050509382019390820190600101612188565b50508684038188015250505061220c8186612134565b9695505050505050565b60208152600061174c6020830184612134565b61ffff83168152604060208201526000611b0a6040830184612134565b604051601f8201601f1916810167ffffffffffffffff8111828210171561226f5761226f612464565b604052919050565b600067ffffffffffffffff82111561229157612291612464565b50601f01601f191660200190565b600082198211156122b2576122b2612435565b500190565b600063ffffffff8083168185168083038211156122d6576122d6612435565b01949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561231757612317612435565b500290565b60008160030b8360030b828112817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000000183128115161561235e5761235e612435565b81637fffffff01831381161561237657612376612435565b5090039392505050565b60008282101561239257612392612435565b500390565b60005b838110156123b257818101518382015260200161239a565b83811115611b925750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156123f5576123f5612435565b5060010190565b600082612430577f4e487b710000000000000000000000000000000000000000000000000000000081526012600452602481fd5b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146124b557600080fd5b5056fea2646970667358221220ae0dd6139ae0cb36a2718e587e540353a25d46471a76819b506675195c4767d464736f6c63430008040033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80633f15457f116100765780637dc0d1d01161005b5780637dc0d1d0146101705780638bbedf7514610190578063be27b22c146101a357600080fd5b80633f15457f1461013d5780637adbf9731461015d57600080fd5b806301ffc9a7146100a85780631ecfc411146100d0578063224199c2146100e557806330349ebe146100f8575b600080fd5b6100bb6100b6366004611e6a565b6101b6565b60405190151581526020015b60405180910390f35b6100e36100de3660046120ae565b61024f565b005b6100e36100f3366004611fa1565b610414565b6002546101189073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c7565b6001546101189073ffffffffffffffffffffffffffffffffffffffff1681565b6100e361016b3660046120ae565b6108e1565b6000546101189073ffffffffffffffffffffffffffffffffffffffff1681565b6100e361019e366004611f1d565b610a9d565b6100e36101b136600461204d565b610b5c565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061024957507fffffffff0000000000000000000000000000000000000000000000000000000082167f17d8f49b00000000000000000000000000000000000000000000000000000000145b92915050565b6001546040517f02571be30000000000000000000000000000000000000000000000000000000081526000600482018190529173ffffffffffffffffffffffffffffffffffffffff16906302571be39060240160206040518083038186803b1580156102ba57600080fd5b505afa1580156102ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f29190611e16565b905060008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561033c57600080fd5b505afa158015610350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103749190611e16565b90503373ffffffffffffffffffffffffffffffffffffffff82161461039857600080fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85169081179091556040519081527f9176b7f47e4504df5e5516c99d90d82ac7cbd49cc77e7f22ba2ac2f2e3a3eba8906020015b60405180910390a1505050565b6000546040517f435cc16200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063435cc1629061046c9087908790600401612160565b600060405180830381600087803b15801561048657600080fd5b505af115801561049a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104c29190810190611eaa565b925060008060006104d38887610c30565b919450925090503373ffffffffffffffffffffffffffffffffffffffff821614610584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f6e6c79206f776e65722063616e2063616c6c2070726f7665416e64436c616960448201527f6d576974685265736f6c7665720000000000000000000000000000000000000060648201526084015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8416156108345773ffffffffffffffffffffffffffffffffffffffff8516610643576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f43616e6e6f74207365742061646472206966207265736f6c766572206973206e60448201527f6f74207365740000000000000000000000000000000000000000000000000000606482015260840161057b565b6001546040517f5ef2c7f0000000000000000000000000000000000000000000000000000000008152600481018590526024810184905230604482015273ffffffffffffffffffffffffffffffffffffffff87811660648301526000608483015290911690635ef2c7f09060a401600060405180830381600087803b1580156106cb57600080fd5b505af11580156106df573d6000803e3d6000fd5b5050505060008383604051602001610701929190918252602082015260400190565b60408051808303601f190181529082905280516020909101207fd5fa2b000000000000000000000000000000000000000000000000000000000082526004820181905273ffffffffffffffffffffffffffffffffffffffff878116602484015290925087169063d5fa2b0090604401600060405180830381600087803b15801561078a57600080fd5b505af115801561079e573d6000803e3d6000fd5b50506001546040517f5b0fc9c30000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff86811660248301529091169250635b0fc9c39150604401600060405180830381600087803b15801561081657600080fd5b505af115801561082a573d6000803e3d6000fd5b50505050506108d7565b6001546040517f5ef2c7f0000000000000000000000000000000000000000000000000000000008152600481018590526024810184905273ffffffffffffffffffffffffffffffffffffffff838116604483015287811660648301526000608483015290911690635ef2c7f09060a401600060405180830381600087803b1580156108be57600080fd5b505af11580156108d2573d6000803e3d6000fd5b505050505b5050505050505050565b6001546040517f02571be30000000000000000000000000000000000000000000000000000000081526000600482018190529173ffffffffffffffffffffffffffffffffffffffff16906302571be39060240160206040518083038186803b15801561094c57600080fd5b505afa158015610960573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109849190611e16565b905060008173ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109ce57600080fd5b505afa1580156109e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a069190611e16565b90503373ffffffffffffffffffffffffffffffffffffffff821614610a2a57600080fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85169081179091556040519081527fb3eacd0e351fafdfefdec84e1cd19679b38dbcd63ea7c2c24da17fd2bc3b3c0e90602001610407565b6000546040517f435cc16200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063435cc16290610af59085908590600401612160565b600060405180830381600087803b158015610b0f57600080fd5b505af1158015610b23573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4b9190810190611eaa565b9050610b578382610b5c565b505050565b6000806000610b6b8585610c30565b6001546040517f06ab5923000000000000000000000000000000000000000000000000000000008152600481018590526024810184905273ffffffffffffffffffffffffffffffffffffffff808416604483015294975092955090935091909116906306ab592390606401602060405180830381600087803b158015610bf057600080fd5b505af1158015610c04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c289190611e52565b505050505050565b6000808080610c3f8682610e6e565b60ff169050610c5086600183610eb9565b92506000610c83610c6283600161229f565b6001848a51610c719190612380565b610c7b9190612380565b899190610edd565b6002546040517f4f89059e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634f89059e90610cda908490600401612216565b60206040518083038186803b158015610cf257600080fd5b505afa158015610d06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2a9190611e32565b610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f506172656e74206e616d65206d7573742062652061207075626c69632073756660448201527f6669780000000000000000000000000000000000000000000000000000000000606482015260840161057b565b610dc1816000610f86565b600054909550610de89073ffffffffffffffffffffffffffffffffffffffff16888861138d565b50604080516020810188905290810186905290935073ffffffffffffffffffffffffffffffffffffffff841690606001604051602081830303815290604052805190602001207fa2e66ce20e6fb2c4f61339c364ad79f15160cf5307230c8bc4d628adbca2ba3989604051610e5d9190612216565b60405180910390a350509250925092565b6000828281518110610ea9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b016020015160f81c905092915050565b8251600090610ec8838561229f565b1115610ed357600080fd5b5091016020012090565b8251606090610eec838561229f565b1115610ef757600080fd5b60008267ffffffffffffffff811115610f39577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015610f63576020820181803683370190505b50905060208082019086860101610f7b82828761164c565b509095945050505050565b600080610f938484610e6e565b60ff16905080610fa7575060009050610249565b6000610fc785610fb7848761229f565b610fc290600161229f565b610f86565b90506000610fe1610fd986600161229f565b879085610eb9565b604080516020810185905290810182905290915060600160408051808303601f190181529082905280516020909101206001547f02571be30000000000000000000000000000000000000000000000000000000083526004830182905290955060009173ffffffffffffffffffffffffffffffffffffffff909116906302571be39060240160206040518083038186803b15801561107e57600080fd5b505afa158015611092573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b69190611e16565b905073ffffffffffffffffffffffffffffffffffffffff811615806110f0575073ffffffffffffffffffffffffffffffffffffffff811630145b61117c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f43616e6e6f7420656e61626c652061206e616d65206f776e656420627920736f60448201527f6d656f6e6520656c736500000000000000000000000000000000000000000000606482015260840161057b565b73ffffffffffffffffffffffffffffffffffffffff8116301461138357826112d0576001546040517f02571be30000000000000000000000000000000000000000000000000000000081526000600482018190529173ffffffffffffffffffffffffffffffffffffffff16906302571be39060240160206040518083038186803b15801561120957600080fd5b505afa15801561121d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112419190611e16565b6040517f8cb8ecec0000000000000000000000000000000000000000000000000000000081526004810185905230602482015290915073ffffffffffffffffffffffffffffffffffffffff821690638cb8ecec90604401600060405180830381600087803b1580156112b257600080fd5b505af11580156112c6573d6000803e3d6000fd5b5050505050611383565b6001546040517f06ab5923000000000000000000000000000000000000000000000000000000008152600481018590526024810184905230604482015273ffffffffffffffffffffffffffffffffffffffff909116906306ab592390606401602060405180830381600087803b15801561134957600080fd5b505af115801561135d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113819190611e52565b505b5050505092915050565b6000806113ad604051806040016040528060608152602001600081525090565b6113c5855160056113be919061229f565b82906116c0565b5060408051808201909152600581527f045f656e730000000000000000000000000000000000000000000000000000006020820152611405908290611725565b506114108186611725565b5080516040517f087991bc000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff8a169163087991bc9161146b91601091600401612229565b60606040518083038186803b15801561148357600080fd5b505afa158015611497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114bb91906120ca565b93509150507fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082161580156114ef57508551155b156115035760008094509450505050611644565b855160208701207fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083811691161461153a57600080fd5b60006115468782611753565b90505b805151602082015110156116385761157081608001518361156a91906122b7565b426117b4565b6115fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f444e53207265636f7264206973207374616c653b2072656672657368206f722060448201527f64656c657465206974206265666f72652070726f63656564696e672e00000000606482015260840161057b565b60008061160d898460a001516117cd565b92509050811561162857965060019550611644945050505050565b505061163381611840565b611549565b50600080945094505050505b935093915050565b60208110611684578151835261166360208461229f565b925061167060208361229f565b915061167d602082612380565b905061164c565b905182516020929092036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199091169116179052565b6040805180820190915260608152600060208201526116e06020836123fc565b15611708576116f06020836123fc565b6116fb906020612380565b611705908361229f565b91505b506020828101829052604080518085526000815290920101905290565b60408051808201909152606081526000602082015261174c83846000015151848551611928565b9392505050565b6117a16040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b82815260c0810182905261024981611840565b6000806117c1838561231c565b60030b12159392505050565b6000805b83518310156118325760006117e68585610e6e565b60ff1690506117f660018561229f565b9350600080611806878785611a30565b92509050811561181e57935060019250611839915050565b611828838761229f565b95505050506117d1565b5060009050805b9250929050565b60c081015160208201819052815151116118575750565b600061186b82600001518360200151611a8c565b826020015161187a919061229f565b82519091506118899082611b12565b61ffff16604083015261189d60028261229f565b82519091506118ac9082611b12565b61ffff1660608301526118c060028261229f565b82519091506118cf9082611b3a565b63ffffffff1660808301526118e560048261229f565b82519091506000906118f79083611b12565b61ffff16905061190860028361229f565b60a08401819052915061191b818361229f565b60c0909301929092525050565b604080518082019091526060815260006020820152825182111561194b57600080fd5b602085015161195a838661229f565b111561198d5761198d8561197d87602001518786611978919061229f565b611b64565b6119889060026122df565b611b7b565b6000808651805187602083010193508088870111156119ac5787860182525b505050602084015b602084106119ec57805182526119cb60208361229f565b91506119d860208261229f565b90506119e5602085612380565b93506119b4565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208690036101000a019081169019919091161790525083949350505050565b600080611a3d8585611b3a565b63ffffffff1663613d307814611a5857506000905080611644565b602c831015611a6c57506000905080611644565b611a8085611a7b86600461229f565b611b98565b91509150935093915050565b6000815b83518110611ac7577f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000611ad38583610e6e565b60ff169050611ae381600161229f565b611aed908361229f565b915080611afa5750611b00565b50611a90565b611b0a8382612380565b949350505050565b8151600090611b2283600261229f565b1115611b2d57600080fd5b50016002015161ffff1690565b8151600090611b4a83600461229f565b1115611b5557600080fd5b50016004015163ffffffff1690565b600081831115611b75575081610249565b50919050565b8151611b8783836116c0565b50611b928382611725565b50505050565b6000806028838551611baa9190612380565b1015611bbb57506000905080611839565b6000835b611bca85602861229f565b811015611c775760049190911b906000611be48783610e6e565b60ff16905060308110158015611bfa5750603a81105b15611c1357611c0a603082612380565b83179250611c64565b60418110158015611c245750604781105b15611c3457611c0a603782612380565b60618110158015611c455750606781105b15611c5557611c0a605782612380565b60008094509450505050611839565b5080611c6f816123c3565b915050611bbf565b50946001945092505050565b600082601f830112611c93578081fd5b8135602067ffffffffffffffff80831115611cb057611cb0612464565b8260051b611cbf838201612246565b8481528381019087850183890186018a1015611cd9578788fd5b8793505b86841015611d1657803585811115611cf3578889fd5b611d018b88838d0101611d74565b84525060019390930192918501918501611cdd565b5098975050505050505050565b600082601f830112611d33578081fd5b8135611d46611d4182612277565b612246565b818152846020838601011115611d5a578283fd5b816020850160208301379081016020019190915292915050565b600060408284031215611d85578081fd5b6040516040810167ffffffffffffffff8282108183111715611da957611da9612464565b816040528293508435915080821115611dc157600080fd5b611dcd86838701611d23565b83526020850135915080821115611de357600080fd5b50611df085828601611d23565b6020830152505092915050565b805163ffffffff81168114611e1157600080fd5b919050565b600060208284031215611e27578081fd5b815161174c81612493565b600060208284031215611e43578081fd5b8151801515811461174c578182fd5b600060208284031215611e63578081fd5b5051919050565b600060208284031215611e7b578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461174c578182fd5b600060208284031215611ebb578081fd5b815167ffffffffffffffff811115611ed1578182fd5b8201601f81018413611ee1578182fd5b8051611eef611d4182612277565b818152856020838501011115611f03578384fd5b611f14826020830160208601612397565b95945050505050565b600080600060608486031215611f31578182fd5b833567ffffffffffffffff80821115611f48578384fd5b611f5487838801611d23565b94506020860135915080821115611f69578384fd5b611f7587838801611c83565b93506040860135915080821115611f8a578283fd5b50611f9786828701611d23565b9150509250925092565b600080600080600060a08688031215611fb8578081fd5b853567ffffffffffffffff80821115611fcf578283fd5b611fdb89838a01611d23565b96506020880135915080821115611ff0578283fd5b611ffc89838a01611c83565b95506040880135915080821115612011578283fd5b5061201e88828901611d23565b935050606086013561202f81612493565b9150608086013561203f81612493565b809150509295509295909350565b6000806040838503121561205f578182fd5b823567ffffffffffffffff80821115612076578384fd5b61208286838701611d23565b93506020850135915080821115612097578283fd5b506120a485828601611d23565b9150509250929050565b6000602082840312156120bf578081fd5b813561174c81612493565b6000806000606084860312156120de578081fd5b6120e784611dfd565b92506120f560208501611dfd565b915060408401517fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081168114612129578182fd5b809150509250925092565b6000815180845261214c816020860160208601612397565b601f01601f19169290920160200192915050565b6000604080830181845280865180835260608601915060608160051b87010192506020808901865b838110156121f6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0898703018552815180518888526121ca89890182612134565b91850151888303898701529190506121e28183612134565b975050509382019390820190600101612188565b50508684038188015250505061220c8186612134565b9695505050505050565b60208152600061174c6020830184612134565b61ffff83168152604060208201526000611b0a6040830184612134565b604051601f8201601f1916810167ffffffffffffffff8111828210171561226f5761226f612464565b604052919050565b600067ffffffffffffffff82111561229157612291612464565b50601f01601f191660200190565b600082198211156122b2576122b2612435565b500190565b600063ffffffff8083168185168083038211156122d6576122d6612435565b01949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561231757612317612435565b500290565b60008160030b8360030b828112817fffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000000183128115161561235e5761235e612435565b81637fffffff01831381161561237657612376612435565b5090039392505050565b60008282101561239257612392612435565b500390565b60005b838110156123b257818101518382015260200161239a565b83811115611b925750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156123f5576123f5612435565b5060010190565b600082612430577f4e487b710000000000000000000000000000000000000000000000000000000081526012600452602481fd5b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146124b557600080fd5b5056fea2646970667358221220ae0dd6139ae0cb36a2718e587e540353a25d46471a76819b506675195c4767d464736f6c63430008040033",
  "devdoc": {
    "details": "An ENS registrar that allows the owner of a DNS name to claim the      corresponding name in ENS.",
    "kind": "dev",
    "methods": {
      "claim(bytes,bytes)": {
        "details": "Claims a name by proving ownership of its DNS equivalent.",
        "params": {
          "name": "The name to claim, in DNS wire format.",
          "proof": "A DNS RRSet proving ownership of the name. Must be verified        in the DNSSEC oracle before calling. This RRSET must contain a TXT        record for '_ens.' + name, with the value 'a=0x...'. Ownership of        the name will be transferred to the address specified in the TXT        record."
        }
      },
      "proveAndClaim(bytes,(bytes,bytes)[],bytes)": {
        "details": "Submits proofs to the DNSSEC oracle, then claims a name using those proofs.",
        "params": {
          "input": "The data to be passed to the Oracle's `submitProofs` function. The last        proof must be the TXT record required by the registrar.",
          "name": "The name to claim, in DNS wire format.",
          "proof": "The proof record for the first element in input."
        }
      }
    },
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 2810,
        "contract": "contracts/dnsregistrar/DNSRegistrar.sol:DNSRegistrar",
        "label": "oracle",
        "offset": 0,
        "slot": "0",
        "type": "t_contract(DNSSEC)4290"
      },
      {
        "astId": 2813,
        "contract": "contracts/dnsregistrar/DNSRegistrar.sol:DNSRegistrar",
        "label": "ens",
        "offset": 0,
        "slot": "1",
        "type": "t_contract(ENS)12028"
      },
      {
        "astId": 2816,
        "contract": "contracts/dnsregistrar/DNSRegistrar.sol:DNSRegistrar",
        "label": "suffixes",
        "offset": 0,
        "slot": "2",
        "type": "t_contract(PublicSuffixList)3363"
      }
    ],
    "types": {
      "t_contract(DNSSEC)4290": {
        "encoding": "inplace",
        "label": "contract DNSSEC",
        "numberOfBytes": "20"
      },
      "t_contract(ENS)12028": {
        "encoding": "inplace",
        "label": "contract ENS",
        "numberOfBytes": "20"
      },
      "t_contract(PublicSuffixList)3363": {
        "encoding": "inplace",
        "label": "contract PublicSuffixList",
        "numberOfBytes": "20"
      }
    }
  }
}