Contract Address Details

0xcf72f16Ab886776232bea2fcf3689761a0b74EfE

Contract Name
RoleDefinitionResolverV2
Creator
0x09622d–f3281a at 0xad4a58–f33937
Balance
0 VT
Tokens
Fetching tokens...
Transactions
292,187 Transactions
Transfers
0 Transfers
Gas Used
15,678,310,930
Last Balance Update
32019144
Contract name:
RoleDefinitionResolverV2




Optimization enabled
false
Compiler version
v0.8.6+commit.11564f7e




EVM Version
default




Verified at
2022-02-23T04:02:09.935560Z

Constructor Arguments

000000000000000000000000d7cef70ba7efc2035256d828d5287e2d285cd1ac000000000000000000000000eea658026d6cdede4380d3ad030beac911758a93

Arg [0] (address) : 0xd7cef70ba7efc2035256d828d5287e2d285cd1ac
Arg [1] (address) : 0xeea658026d6cdede4380d3ad030beac911758a93

              

Contract source code

// File: @ensdomains/ens-contracts/contracts/registry/ENS.sol

pragma solidity >=0.8.4;

interface ENS {

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

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

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

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

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

    function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual;
    function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual;
    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external virtual returns(bytes32);
    function setResolver(bytes32 node, address resolver) external virtual;
    function setOwner(bytes32 node, address owner) external virtual;
    function setTTL(bytes32 node, uint64 ttl) external virtual;
    function setApprovalForAll(address operator, bool approved) external virtual;
    function owner(bytes32 node) external virtual view returns (address);
    function resolver(bytes32 node) external virtual view returns (address);
    function ttl(bytes32 node) external virtual view returns (uint64);
    function recordExists(bytes32 node) external virtual view returns (bool);
    function isApprovedForAll(address owner, address operator) external virtual view returns (bool);
}

// File: @ensdomains/ens-contracts/contracts/resolvers/ResolverBase.sol

pragma solidity >=0.8.4;
abstract contract ResolverBase {
    bytes4 private constant INTERFACE_META_ID = 0x01ffc9a7;

    function supportsInterface(bytes4 interfaceID) virtual public pure returns(bool) {
        return interfaceID == INTERFACE_META_ID;
    }

    function isAuthorised(bytes32 node) internal virtual view returns(bool);

    modifier authorised(bytes32 node) {
        require(isAuthorised(node));
        _;
    }

    function bytesToAddress(bytes memory b) internal pure returns(address payable a) {
        require(b.length == 20);
        assembly {
            a := div(mload(add(b, 32)), exp(256, 12))
        }
    }

    function addressToBytes(address a) internal pure returns(bytes memory b) {
        b = new bytes(20);
        assembly {
            mstore(add(b, 32), mul(a, exp(256, 12)))
        }
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/profiles/ABIResolver.sol

pragma solidity >=0.8.4;


abstract contract ABIResolver is ResolverBase {
    bytes4 constant private ABI_INTERFACE_ID = 0x2203ab56;

    event ABIChanged(bytes32 indexed node, uint256 indexed contentType);

    mapping(bytes32=>mapping(uint256=>bytes)) abis;

    /**
     * Sets the ABI associated with an ENS node.
     * Nodes may have one ABI of each content type. To remove an ABI, set it to
     * the empty string.
     * @param node The node to update.
     * @param contentType The content type of the ABI
     * @param data The ABI data.
     */
    function setABI(bytes32 node, uint256 contentType, bytes calldata data) external authorised(node) {
        // Content types must be powers of 2
        require(((contentType - 1) & contentType) == 0);

        abis[node][contentType] = data;
        emit ABIChanged(node, contentType);
    }

    /**
     * Returns the ABI associated with an ENS node.
     * Defined in EIP205.
     * @param node The ENS node to query
     * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.
     * @return contentType The content type of the return value
     * @return data The ABI data
     */
    function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory) {
        mapping(uint256=>bytes) storage abiset = abis[node];

        for (uint256 contentType = 1; contentType <= contentTypes; contentType <<= 1) {
            if ((contentType & contentTypes) != 0 && abiset[contentType].length > 0) {
                return (contentType, abiset[contentType]);
            }
        }

        return (0, bytes(""));
    }

    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
        return interfaceID == ABI_INTERFACE_ID || super.supportsInterface(interfaceID);
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/profiles/AddrResolver.sol

pragma solidity >=0.8.4;


abstract contract AddrResolver is ResolverBase {
    bytes4 constant private ADDR_INTERFACE_ID = 0x3b3b57de;
    bytes4 constant private ADDRESS_INTERFACE_ID = 0xf1cb7e06;
    uint constant private COIN_TYPE_ETH = 60;

    event AddrChanged(bytes32 indexed node, address a);
    event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);

    mapping(bytes32=>mapping(uint=>bytes)) _addresses;

    /**
     * Sets the address associated with an ENS node.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param a The address to set.
     */
    function setAddr(bytes32 node, address a) external authorised(node) {
        setAddr(node, COIN_TYPE_ETH, addressToBytes(a));
    }

    /**
     * Returns the address associated with an ENS node.
     * @param node The ENS node to query.
     * @return The associated address.
     */
    function addr(bytes32 node) public view returns (address payable) {
        bytes memory a = addr(node, COIN_TYPE_ETH);
        if(a.length == 0) {
            return payable(0);
        }
        return bytesToAddress(a);
    }

    function setAddr(bytes32 node, uint coinType, bytes memory a) public authorised(node) {
        emit AddressChanged(node, coinType, a);
        if(coinType == COIN_TYPE_ETH) {
            emit AddrChanged(node, bytesToAddress(a));
        }
        _addresses[node][coinType] = a;
    }

    function addr(bytes32 node, uint coinType) public view returns(bytes memory) {
        return _addresses[node][coinType];
    }

    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
        return interfaceID == ADDR_INTERFACE_ID || interfaceID == ADDRESS_INTERFACE_ID || super.supportsInterface(interfaceID);
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/profiles/ContentHashResolver.sol

pragma solidity >=0.8.4;


abstract contract ContentHashResolver is ResolverBase {
    bytes4 constant private CONTENT_HASH_INTERFACE_ID = 0xbc1c58d1;

    event ContenthashChanged(bytes32 indexed node, bytes hash);

    mapping(bytes32=>bytes) hashes;

    /**
     * Sets the contenthash associated with an ENS node.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param hash The contenthash to set
     */
    function setContenthash(bytes32 node, bytes calldata hash) external authorised(node) {
        hashes[node] = hash;
        emit ContenthashChanged(node, hash);
    }

    /**
     * Returns the contenthash associated with an ENS node.
     * @param node The ENS node to query.
     * @return The associated contenthash.
     */
    function contenthash(bytes32 node) external view returns (bytes memory) {
        return hashes[node];
    }

    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
        return interfaceID == CONTENT_HASH_INTERFACE_ID || super.supportsInterface(interfaceID);
    }
}

// File: @ensdomains/ens-contracts/contracts/dnssec-oracle/BytesUtils.sol

pragma solidity ^0.8.4;

library BytesUtils {
    /*
    * @dev Returns the keccak-256 hash of a byte range.
    * @param self The byte string to hash.
    * @param offset The position to start hashing at.
    * @param len The number of bytes to hash.
    * @return The hash of the byte range.
    */
    function keccak(bytes memory self, uint offset, uint len) internal pure returns (bytes32 ret) {
        require(offset + len <= self.length);
        assembly {
            ret := keccak256(add(add(self, 32), offset), len)
        }
    }


    /*
    * @dev Returns a positive number if `other` comes lexicographically after
    *      `self`, a negative number if it comes before, or zero if the
    *      contents of the two bytes are equal.
    * @param self The first bytes to compare.
    * @param other The second bytes to compare.
    * @return The result of the comparison.
    */
    function compare(bytes memory self, bytes memory other) internal pure returns (int) {
        return compare(self, 0, self.length, other, 0, other.length);
    }

    /*
    * @dev Returns a positive number if `other` comes lexicographically after
    *      `self`, a negative number if it comes before, or zero if the
    *      contents of the two bytes are equal. Comparison is done per-rune,
    *      on unicode codepoints.
    * @param self The first bytes to compare.
    * @param offset The offset of self.
    * @param len    The length of self.
    * @param other The second bytes to compare.
    * @param otheroffset The offset of the other string.
    * @param otherlen    The length of the other string.
    * @return The result of the comparison.
    */
    function compare(bytes memory self, uint offset, uint len, bytes memory other, uint otheroffset, uint otherlen) internal pure returns (int) {
        uint shortest = len;
        if (otherlen < len)
        shortest = otherlen;

        uint selfptr;
        uint otherptr;

        assembly {
            selfptr := add(self, add(offset, 32))
            otherptr := add(other, add(otheroffset, 32))
        }
        for (uint idx = 0; idx < shortest; idx += 32) {
            uint a;
            uint b;
            assembly {
                a := mload(selfptr)
                b := mload(otherptr)
            }
            if (a != b) {
                // Mask out irrelevant bytes and check again
                uint mask;
                if (shortest > 32) {
                    mask = type(uint256).max;
                } else {
                    mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);
                }
                int diff = int(a & mask) - int(b & mask);
                if (diff != 0)
                return diff;
            }
            selfptr += 32;
            otherptr += 32;
        }

        return int(len) - int(otherlen);
    }

    /*
    * @dev Returns true if the two byte ranges are equal.
    * @param self The first byte range to compare.
    * @param offset The offset into the first byte range.
    * @param other The second byte range to compare.
    * @param otherOffset The offset into the second byte range.
    * @param len The number of bytes to compare
    * @return True if the byte ranges are equal, false otherwise.
    */
    function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset, uint len) internal pure returns (bool) {
        return keccak(self, offset, len) == keccak(other, otherOffset, len);
    }

    /*
    * @dev Returns true if the two byte ranges are equal with offsets.
    * @param self The first byte range to compare.
    * @param offset The offset into the first byte range.
    * @param other The second byte range to compare.
    * @param otherOffset The offset into the second byte range.
    * @return True if the byte ranges are equal, false otherwise.
    */
    function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset) internal pure returns (bool) {
        return keccak(self, offset, self.length - offset) == keccak(other, otherOffset, other.length - otherOffset);
    }

    /*
    * @dev Compares a range of 'self' to all of 'other' and returns True iff
    *      they are equal.
    * @param self The first byte range to compare.
    * @param offset The offset into the first byte range.
    * @param other The second byte range to compare.
    * @return True if the byte ranges are equal, false otherwise.
    */
    function equals(bytes memory self, uint offset, bytes memory other) internal pure returns (bool) {
        return self.length >= offset + other.length && equals(self, offset, other, 0, other.length);
    }

    /*
    * @dev Returns true if the two byte ranges are equal.
    * @param self The first byte range to compare.
    * @param other The second byte range to compare.
    * @return True if the byte ranges are equal, false otherwise.
    */
    function equals(bytes memory self, bytes memory other) internal pure returns(bool) {
        return self.length == other.length && equals(self, 0, other, 0, self.length);
    }

    /*
    * @dev Returns the 8-bit number at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes
    * @return The specified 8 bits of the string, interpreted as an integer.
    */
    function readUint8(bytes memory self, uint idx) internal pure returns (uint8 ret) {
        return uint8(self[idx]);
    }

    /*
    * @dev Returns the 16-bit number at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes
    * @return The specified 16 bits of the string, interpreted as an integer.
    */
    function readUint16(bytes memory self, uint idx) internal pure returns (uint16 ret) {
        require(idx + 2 <= self.length);
        assembly {
            ret := and(mload(add(add(self, 2), idx)), 0xFFFF)
        }
    }

    /*
    * @dev Returns the 32-bit number at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes
    * @return The specified 32 bits of the string, interpreted as an integer.
    */
    function readUint32(bytes memory self, uint idx) internal pure returns (uint32 ret) {
        require(idx + 4 <= self.length);
        assembly {
            ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF)
        }
    }

    /*
    * @dev Returns the 32 byte value at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes
    * @return The specified 32 bytes of the string.
    */
    function readBytes32(bytes memory self, uint idx) internal pure returns (bytes32 ret) {
        require(idx + 32 <= self.length);
        assembly {
            ret := mload(add(add(self, 32), idx))
        }
    }

    /*
    * @dev Returns the 32 byte value at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes
    * @return The specified 32 bytes of the string.
    */
    function readBytes20(bytes memory self, uint idx) internal pure returns (bytes20 ret) {
        require(idx + 20 <= self.length);
        assembly {
            ret := and(mload(add(add(self, 32), idx)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000)
        }
    }

    /*
    * @dev Returns the n byte value at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes.
    * @param len The number of bytes.
    * @return The specified 32 bytes of the string.
    */
    function readBytesN(bytes memory self, uint idx, uint len) internal pure returns (bytes32 ret) {
        require(len <= 32);
        require(idx + len <= self.length);
        assembly {
            let mask := not(sub(exp(256, sub(32, len)), 1))
            ret := and(mload(add(add(self, 32), idx)),  mask)
        }
    }

    function memcpy(uint dest, uint src, uint len) private pure {
        // Copy word-length chunks while possible
        for (; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        unchecked {
            uint mask = (256 ** (32 - len)) - 1;
            assembly {
                let srcpart := and(mload(src), not(mask))
                let destpart := and(mload(dest), mask)
                mstore(dest, or(destpart, srcpart))
            }
        }
    }

    /*
    * @dev Copies a substring into a new byte string.
    * @param self The byte string to copy from.
    * @param offset The offset to start copying at.
    * @param len The number of bytes to copy.
    */
    function substring(bytes memory self, uint offset, uint len) internal pure returns(bytes memory) {
        require(offset + len <= self.length);

        bytes memory ret = new bytes(len);
        uint dest;
        uint src;

        assembly {
            dest := add(ret, 32)
            src := add(add(self, 32), offset)
        }
        memcpy(dest, src, len);

        return ret;
    }

    // Maps characters from 0x30 to 0x7A to their base32 values.
    // 0xFF represents invalid characters in that range.
    bytes constant base32HexTable = hex'00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F';

    /**
     * @dev Decodes unpadded base32 data of up to one word in length.
     * @param self The data to decode.
     * @param off Offset into the string to start at.
     * @param len Number of characters to decode.
     * @return The decoded data, left aligned.
     */
    function base32HexDecodeWord(bytes memory self, uint off, uint len) internal pure returns(bytes32) {
        require(len <= 52);

        uint ret = 0;
        uint8 decoded;
        for(uint i = 0; i < len; i++) {
            bytes1 char = self[off + i];
            require(char >= 0x30 && char <= 0x7A);
            decoded = uint8(base32HexTable[uint(uint8(char)) - 0x30]);
            require(decoded <= 0x20);
            if(i == len - 1) {
                break;
            }
            ret = (ret << 5) | decoded;
        }

        uint bitlen = len * 5;
        if(len % 8 == 0) {
            // Multiple of 8 characters, no padding
            ret = (ret << 5) | decoded;
        } else if(len % 8 == 2) {
            // Two extra characters - 1 byte
            ret = (ret << 3) | (decoded >> 2);
            bitlen -= 2;
        } else if(len % 8 == 4) {
            // Four extra characters - 2 bytes
            ret = (ret << 1) | (decoded >> 4);
            bitlen -= 4;
        } else if(len % 8 == 5) {
            // Five extra characters - 3 bytes
            ret = (ret << 4) | (decoded >> 1);
            bitlen -= 1;
        } else if(len % 8 == 7) {
            // Seven extra characters - 4 bytes
            ret = (ret << 2) | (decoded >> 3);
            bitlen -= 3;
        } else {
            revert();
        }

        return bytes32(ret << (256 - bitlen));
    }
}

// File: @ensdomains/buffer/contracts/Buffer.sol

pragma solidity ^0.8.4;

/**
* @dev A library for working with mutable byte buffers in Solidity.
*
* Byte buffers are mutable and expandable, and provide a variety of primitives
* for writing to them. At any time you can fetch a bytes object containing the
* current contents of the buffer. The bytes object should not be stored between
* operations, as it may change due to resizing of the buffer.
*/
library Buffer {
    /**
    * @dev Represents a mutable buffer. Buffers have a current value (buf) and
    *      a capacity. The capacity may be longer than the current value, in
    *      which case it can be extended without the need to allocate more memory.
    */
    struct buffer {
        bytes buf;
        uint capacity;
    }

    /**
    * @dev Initializes a buffer with an initial capacity.
    * @param buf The buffer to initialize.
    * @param capacity The number of bytes of space to allocate the buffer.
    * @return The buffer, for chaining.
    */
    function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
        if (capacity % 32 != 0) {
            capacity += 32 - (capacity % 32);
        }
        // Allocate space for the buffer data
        buf.capacity = capacity;
        assembly {
            let ptr := mload(0x40)
            mstore(buf, ptr)
            mstore(ptr, 0)
            mstore(0x40, add(32, add(ptr, capacity)))
        }
        return buf;
    }

    /**
    * @dev Initializes a new buffer from an existing bytes object.
    *      Changes to the buffer may mutate the original value.
    * @param b The bytes object to initialize the buffer with.
    * @return A new buffer.
    */
    function fromBytes(bytes memory b) internal pure returns(buffer memory) {
        buffer memory buf;
        buf.buf = b;
        buf.capacity = b.length;
        return buf;
    }

    function resize(buffer memory buf, uint capacity) private pure {
        bytes memory oldbuf = buf.buf;
        init(buf, capacity);
        append(buf, oldbuf);
    }

    function max(uint a, uint b) private pure returns(uint) {
        if (a > b) {
            return a;
        }
        return b;
    }

    /**
    * @dev Sets buffer length to 0.
    * @param buf The buffer to truncate.
    * @return The original buffer, for chaining..
    */
    function truncate(buffer memory buf) internal pure returns (buffer memory) {
        assembly {
            let bufptr := mload(buf)
            mstore(bufptr, 0)
        }
        return buf;
    }

    /**
    * @dev Writes a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The start offset to write to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) {
        require(len <= data.length);

        if (off + len > buf.capacity) {
            resize(buf, max(buf.capacity, len + off) * 2);
        }

        uint dest;
        uint src;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Start address = buffer address + offset + sizeof(buffer length)
            dest := add(add(bufptr, 32), off)
            // Update buffer length if we're extending it
            if gt(add(len, off), buflen) {
                mstore(bufptr, add(len, off))
            }
            src := add(data, 32)
        }

        // Copy word-length chunks while possible
        for (; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        unchecked {
            uint mask = (256 ** (32 - len)) - 1;
            assembly {
                let srcpart := and(mload(src), not(mask))
                let destpart := and(mload(dest), mask)
                mstore(dest, or(destpart, srcpart))
            }
        }

        return buf;
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, len);
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, data.length);
    }

    /**
    * @dev Writes a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write the byte at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) {
        if (off >= buf.capacity) {
            resize(buf, buf.capacity * 2);
        }

        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Address = buffer address + sizeof(buffer length) + off
            let dest := add(add(bufptr, off), 32)
            mstore8(dest, data)
            // Update buffer length if we extended it
            if eq(off, buflen) {
                mstore(bufptr, add(buflen, 1))
            }
        }
        return buf;
    }

    /**
    * @dev Appends a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {
        return writeUint8(buf, buf.buf.length, data);
    }

    /**
    * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
    *      exceed the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (left-aligned).
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, (len + off) * 2);
        }

        unchecked {
            uint mask = (256 ** len) - 1;
            // Right-align data
            data = data >> (8 * (32 - len));
            assembly {
                // Memory address of the buffer data
                let bufptr := mload(buf)
                // Address = buffer address + sizeof(buffer length) + off + len
                let dest := add(add(bufptr, off), len)
                mstore(dest, or(and(mload(dest), not(mask)), data))
                // Update buffer length if we extended it
                if gt(add(off, len), mload(bufptr)) {
                    mstore(bufptr, add(off, len))
                }
            }
        }
        return buf;
    }

    /**
    * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, off, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chhaining.
    */
    function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, 32);
    }

    /**
    * @dev Writes an integer to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (right-aligned).
    * @return The original buffer, for chaining.
    */
    function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, (len + off) * 2);
        }

        uint mask = (256 ** len) - 1;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Address = buffer address + off + sizeof(buffer length) + len
            let dest := add(add(bufptr, off), len)
            mstore(dest, or(and(mload(dest), not(mask)), data))
            // Update buffer length if we extended it
            if gt(add(off, len), mload(bufptr)) {
                mstore(bufptr, add(off, len))
            }
        }
        return buf;
    }

    /**
     * @dev Appends a byte to the end of the buffer. Resizes if doing so would
     * exceed the capacity of the buffer.
     * @param buf The buffer to append to.
     * @param data The data to append.
     * @return The original buffer.
     */
    function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) {
        return writeInt(buf, buf.buf.length, data, len);
    }
}

// File: @ensdomains/ens-contracts/contracts/dnssec-oracle/RRUtils.sol

pragma solidity ^0.8.4;



/**
* @dev RRUtils is a library that provides utilities for parsing DNS resource records.
*/
library RRUtils {
    using BytesUtils for *;
    using Buffer for *;

    /**
    * @dev Returns the number of bytes in the DNS name at 'offset' in 'self'.
    * @param self The byte array to read a name from.
    * @param offset The offset to start reading at.
    * @return The length of the DNS name at 'offset', in bytes.
    */
    function nameLength(bytes memory self, uint offset) internal pure returns(uint) {
        uint idx = offset;
        while (true) {
            assert(idx < self.length);
            uint labelLen = self.readUint8(idx);
            idx += labelLen + 1;
            if (labelLen == 0) {
                break;
            }
        }
        return idx - offset;
    }

    /**
    * @dev Returns a DNS format name at the specified offset of self.
    * @param self The byte array to read a name from.
    * @param offset The offset to start reading at.
    * @return ret The name.
    */
    function readName(bytes memory self, uint offset) internal pure returns(bytes memory ret) {
        uint len = nameLength(self, offset);
        return self.substring(offset, len);
    }

    /**
    * @dev Returns the number of labels in the DNS name at 'offset' in 'self'.
    * @param self The byte array to read a name from.
    * @param offset The offset to start reading at.
    * @return The number of labels in the DNS name at 'offset', in bytes.
    */
    function labelCount(bytes memory self, uint offset) internal pure returns(uint) {
        uint count = 0;
        while (true) {
            assert(offset < self.length);
            uint labelLen = self.readUint8(offset);
            offset += labelLen + 1;
            if (labelLen == 0) {
                break;
            }
            count += 1;
        }
        return count;
    }

    uint constant RRSIG_TYPE = 0;
    uint constant RRSIG_ALGORITHM = 2;
    uint constant RRSIG_LABELS = 3;
    uint constant RRSIG_TTL = 4;
    uint constant RRSIG_EXPIRATION = 8;
    uint constant RRSIG_INCEPTION = 12;
    uint constant RRSIG_KEY_TAG = 16;
    uint constant RRSIG_SIGNER_NAME = 18;

    struct SignedSet {
        uint16 typeCovered;
        uint8 algorithm;
        uint8 labels;
        uint32 ttl;
        uint32 expiration;
        uint32 inception;
        uint16 keytag;
        bytes signerName;
        bytes data;
        bytes name;
    }

    function readSignedSet(bytes memory data) internal pure returns(SignedSet memory self) {
        self.typeCovered = data.readUint16(RRSIG_TYPE);
        self.algorithm = data.readUint8(RRSIG_ALGORITHM);
        self.labels = data.readUint8(RRSIG_LABELS);
        self.ttl = data.readUint32(RRSIG_TTL);
        self.expiration = data.readUint32(RRSIG_EXPIRATION);
        self.inception = data.readUint32(RRSIG_INCEPTION);
        self.keytag = data.readUint16(RRSIG_KEY_TAG);
        self.signerName = readName(data, RRSIG_SIGNER_NAME);
        self.data = data.substring(RRSIG_SIGNER_NAME + self.signerName.length, data.length - RRSIG_SIGNER_NAME - self.signerName.length);
    }

    function rrs(SignedSet memory rrset) internal pure returns(RRIterator memory) {
        return iterateRRs(rrset.data, 0);
    }

    /**
    * @dev An iterator over resource records.
    */
    struct RRIterator {
        bytes data;
        uint offset;
        uint16 dnstype;
        uint16 class;
        uint32 ttl;
        uint rdataOffset;
        uint nextOffset;
    }

    /**
    * @dev Begins iterating over resource records.
    * @param self The byte string to read from.
    * @param offset The offset to start reading at.
    * @return ret An iterator object.
    */
    function iterateRRs(bytes memory self, uint offset) internal pure returns (RRIterator memory ret) {
        ret.data = self;
        ret.nextOffset = offset;
        next(ret);
    }

    /**
    * @dev Returns true iff there are more RRs to iterate.
    * @param iter The iterator to check.
    * @return True iff the iterator has finished.
    */
    function done(RRIterator memory iter) internal pure returns(bool) {
        return iter.offset >= iter.data.length;
    }

    /**
    * @dev Moves the iterator to the next resource record.
    * @param iter The iterator to advance.
    */
    function next(RRIterator memory iter) internal pure {
        iter.offset = iter.nextOffset;
        if (iter.offset >= iter.data.length) {
            return;
        }

        // Skip the name
        uint off = iter.offset + nameLength(iter.data, iter.offset);

        // Read type, class, and ttl
        iter.dnstype = iter.data.readUint16(off);
        off += 2;
        iter.class = iter.data.readUint16(off);
        off += 2;
        iter.ttl = iter.data.readUint32(off);
        off += 4;

        // Read the rdata
        uint rdataLength = iter.data.readUint16(off);
        off += 2;
        iter.rdataOffset = off;
        iter.nextOffset = off + rdataLength;
    }

    /**
    * @dev Returns the name of the current record.
    * @param iter The iterator.
    * @return A new bytes object containing the owner name from the RR.
    */
    function name(RRIterator memory iter) internal pure returns(bytes memory) {
        return iter.data.substring(iter.offset, nameLength(iter.data, iter.offset));
    }

    /**
    * @dev Returns the rdata portion of the current record.
    * @param iter The iterator.
    * @return A new bytes object containing the RR's RDATA.
    */
    function rdata(RRIterator memory iter) internal pure returns(bytes memory) {
        return iter.data.substring(iter.rdataOffset, iter.nextOffset - iter.rdataOffset);
    }

    uint constant DNSKEY_FLAGS = 0;
    uint constant DNSKEY_PROTOCOL = 2;
    uint constant DNSKEY_ALGORITHM = 3;
    uint constant DNSKEY_PUBKEY = 4;

    struct DNSKEY {
        uint16 flags;
        uint8 protocol;
        uint8 algorithm;
        bytes publicKey;
    }

    function readDNSKEY(bytes memory data, uint offset, uint length) internal pure returns(DNSKEY memory self) {
        self.flags = data.readUint16(offset + DNSKEY_FLAGS);
        self.protocol = data.readUint8(offset + DNSKEY_PROTOCOL);
        self.algorithm = data.readUint8(offset + DNSKEY_ALGORITHM);
        self.publicKey = data.substring(offset + DNSKEY_PUBKEY, length - DNSKEY_PUBKEY);
    } 

    uint constant DS_KEY_TAG = 0;
    uint constant DS_ALGORITHM = 2;
    uint constant DS_DIGEST_TYPE = 3;
    uint constant DS_DIGEST = 4;

    struct DS {
        uint16 keytag;
        uint8 algorithm;
        uint8 digestType;
        bytes digest;
    }

    function readDS(bytes memory data, uint offset, uint length) internal pure returns(DS memory self) {
        self.keytag = data.readUint16(offset + DS_KEY_TAG);
        self.algorithm = data.readUint8(offset + DS_ALGORITHM);
        self.digestType = data.readUint8(offset + DS_DIGEST_TYPE);
        self.digest = data.substring(offset + DS_DIGEST, length - DS_DIGEST);
    }

    struct NSEC3 {
        uint8 hashAlgorithm;
        uint8 flags;
        uint16 iterations;
        bytes salt;
        bytes32 nextHashedOwnerName;
        bytes typeBitmap;
    }

    uint constant NSEC3_HASH_ALGORITHM = 0;
    uint constant NSEC3_FLAGS = 1;
    uint constant NSEC3_ITERATIONS = 2;
    uint constant NSEC3_SALT_LENGTH = 4;
    uint constant NSEC3_SALT = 5;

    function readNSEC3(bytes memory data, uint offset, uint length) internal pure returns(NSEC3 memory self) {
        uint end = offset + length;
        self.hashAlgorithm = data.readUint8(offset + NSEC3_HASH_ALGORITHM);
        self.flags = data.readUint8(offset + NSEC3_FLAGS);
        self.iterations = data.readUint16(offset + NSEC3_ITERATIONS);
        uint8 saltLength = data.readUint8(offset + NSEC3_SALT_LENGTH);
        offset = offset + NSEC3_SALT;
        self.salt = data.substring(offset, saltLength);
        offset += saltLength;
        uint8 nextLength = data.readUint8(offset);
        require(nextLength <= 32);
        offset += 1;
        self.nextHashedOwnerName = data.readBytesN(offset, nextLength);
        offset += nextLength;
        self.typeBitmap = data.substring(offset, end - offset);
    }

    function checkTypeBitmap(NSEC3 memory self, uint16 rrtype) internal pure returns(bool) {
        return checkTypeBitmap(self.typeBitmap, 0, rrtype);
    }

    /**
    * @dev Checks if a given RR type exists in a type bitmap.
    * @param bitmap The byte string to read the type bitmap from.
    * @param offset The offset to start reading at.
    * @param rrtype The RR type to check for.
    * @return True if the type is found in the bitmap, false otherwise.
    */
    function checkTypeBitmap(bytes memory bitmap, uint offset, uint16 rrtype) internal pure returns (bool) {
        uint8 typeWindow = uint8(rrtype >> 8);
        uint8 windowByte = uint8((rrtype & 0xff) / 8);
        uint8 windowBitmask = uint8(uint8(1) << (uint8(7) - uint8(rrtype & 0x7)));
        for (uint off = offset; off < bitmap.length;) {
            uint8 window = bitmap.readUint8(off);
            uint8 len = bitmap.readUint8(off + 1);
            if (typeWindow < window) {
                // We've gone past our window; it's not here.
                return false;
            } else if (typeWindow == window) {
                // Check this type bitmap
                if (len <= windowByte) {
                    // Our type is past the end of the bitmap
                    return false;
                }
                return (bitmap.readUint8(off + windowByte + 2) & windowBitmask) != 0;
            } else {
                // Skip this type bitmap
                off += len + 2;
            }
        }

        return false;
    }

    function compareNames(bytes memory self, bytes memory other) internal pure returns (int) {
        if (self.equals(other)) {
            return 0;
        }

        uint off;
        uint otheroff;
        uint prevoff;
        uint otherprevoff;
        uint counts = labelCount(self, 0);
        uint othercounts = labelCount(other, 0);

        // Keep removing labels from the front of the name until both names are equal length
        while (counts > othercounts) {
            prevoff = off;
            off = progress(self, off);
            counts--;
        }

        while (othercounts > counts) {
            otherprevoff = otheroff;
            otheroff = progress(other, otheroff);
            othercounts--;
        }

        // Compare the last nonequal labels to each other
        while (counts > 0 && !self.equals(off, other, otheroff)) {
            prevoff = off;
            off = progress(self, off);
            otherprevoff = otheroff;
            otheroff = progress(other, otheroff);
            counts -= 1;
        }

        if (off == 0) {
            return -1;
        }
        if(otheroff == 0) {
            return 1;
        }

        return self.compare(prevoff + 1, self.readUint8(prevoff), other, otherprevoff + 1, other.readUint8(otherprevoff));
    }

    /**
     * @dev Compares two serial numbers using RFC1982 serial number math.
     */
    function serialNumberGte(uint32 i1, uint32 i2) internal pure returns(bool) {
        return int32(i1) - int32(i2) >= 0;
    }

    function progress(bytes memory body, uint off) internal pure returns(uint) {
        return off + 1 + body.readUint8(off);
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/profiles/DNSResolver.sol

pragma solidity >=0.8.4;



abstract contract DNSResolver is ResolverBase {
    using RRUtils for *;
    using BytesUtils for bytes;

    bytes4 constant private DNS_RECORD_INTERFACE_ID = 0xa8fa5682;
    bytes4 constant private DNS_ZONE_INTERFACE_ID = 0x5c47637c;

    // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.
    event DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record);
    // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.
    event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);
    // DNSZoneCleared is emitted whenever a given node's zone information is cleared.
    event DNSZoneCleared(bytes32 indexed node);

    // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.
    event DNSZonehashChanged(bytes32 indexed node, bytes lastzonehash, bytes zonehash);

    // Zone hashes for the domains.
    // A zone hash is an EIP-1577 content hash in binary format that should point to a
    // resource containing a single zonefile.
    // node => contenthash
    mapping(bytes32=>bytes) private zonehashes;

    // Version the mapping for each zone.  This allows users who have lost
    // track of their entries to effectively delete an entire zone by bumping
    // the version number.
    // node => version
    mapping(bytes32=>uint256) private versions;

    // The records themselves.  Stored as binary RRSETs
    // node => version => name => resource => data
    mapping(bytes32=>mapping(uint256=>mapping(bytes32=>mapping(uint16=>bytes)))) private records;

    // Count of number of entries for a given name.  Required for DNS resolvers
    // when resolving wildcards.
    // node => version => name => number of records
    mapping(bytes32=>mapping(uint256=>mapping(bytes32=>uint16))) private nameEntriesCount;

    /**
     * Set one or more DNS records.  Records are supplied in wire-format.
     * Records with the same node/name/resource must be supplied one after the
     * other to ensure the data is updated correctly. For example, if the data
     * was supplied:
     *     a.example.com IN A 1.2.3.4
     *     a.example.com IN A 5.6.7.8
     *     www.example.com IN CNAME a.example.com.
     * then this would store the two A records for a.example.com correctly as a
     * single RRSET, however if the data was supplied:
     *     a.example.com IN A 1.2.3.4
     *     www.example.com IN CNAME a.example.com.
     *     a.example.com IN A 5.6.7.8
     * then this would store the first A record, the CNAME, then the second A
     * record which would overwrite the first.
     *
     * @param node the namehash of the node for which to set the records
     * @param data the DNS wire format records to set
     */
    function setDNSRecords(bytes32 node, bytes calldata data) external authorised(node) {
        uint16 resource = 0;
        uint256 offset = 0;
        bytes memory name;
        bytes memory value;
        bytes32 nameHash;
        // Iterate over the data to add the resource records
        for (RRUtils.RRIterator memory iter = data.iterateRRs(0); !iter.done(); iter.next()) {
            if (resource == 0) {
                resource = iter.dnstype;
                name = iter.name();
                nameHash = keccak256(abi.encodePacked(name));
                value = bytes(iter.rdata());
            } else {
                bytes memory newName = iter.name();
                if (resource != iter.dnstype || !name.equals(newName)) {
                    setDNSRRSet(node, name, resource, data, offset, iter.offset - offset, value.length == 0);
                    resource = iter.dnstype;
                    offset = iter.offset;
                    name = newName;
                    nameHash = keccak256(name);
                    value = bytes(iter.rdata());
                }
            }
        }
        if (name.length > 0) {
            setDNSRRSet(node, name, resource, data, offset, data.length - offset, value.length == 0);
        }
    }

    /**
     * Obtain a DNS record.
     * @param node the namehash of the node for which to fetch the record
     * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record
     * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types
     * @return the DNS record in wire format if present, otherwise empty
     */
    function dnsRecord(bytes32 node, bytes32 name, uint16 resource) public view returns (bytes memory) {
        return records[node][versions[node]][name][resource];
    }

    /**
     * Check if a given node has records.
     * @param node the namehash of the node for which to check the records
     * @param name the namehash of the node for which to check the records
     */
    function hasDNSRecords(bytes32 node, bytes32 name) public view returns (bool) {
        return (nameEntriesCount[node][versions[node]][name] != 0);
    }

    /**
     * Clear all information for a DNS zone.
     * @param node the namehash of the node for which to clear the zone
     */
    function clearDNSZone(bytes32 node) public authorised(node) {
        versions[node]++;
        emit DNSZoneCleared(node);
    }

    /**
     * setZonehash sets the hash for the zone.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param hash The zonehash to set
     */
    function setZonehash(bytes32 node, bytes calldata hash) external authorised(node) {
        bytes memory oldhash = zonehashes[node];
        zonehashes[node] = hash;
        emit DNSZonehashChanged(node, oldhash, hash);
    }

    /**
     * zonehash obtains the hash for the zone.
     * @param node The ENS node to query.
     * @return The associated contenthash.
     */
    function zonehash(bytes32 node) external view returns (bytes memory) {
        return zonehashes[node];
    }

    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
        return interfaceID == DNS_RECORD_INTERFACE_ID ||
               interfaceID == DNS_ZONE_INTERFACE_ID ||
               super.supportsInterface(interfaceID);
    }

    function setDNSRRSet(
        bytes32 node,
        bytes memory name,
        uint16 resource,
        bytes memory data,
        uint256 offset,
        uint256 size,
        bool deleteRecord) private
    {
        uint256 version = versions[node];
        bytes32 nameHash = keccak256(name);
        bytes memory rrData = data.substring(offset, size);
        if (deleteRecord) {
            if (records[node][version][nameHash][resource].length != 0) {
                nameEntriesCount[node][version][nameHash]--;
            }
            delete(records[node][version][nameHash][resource]);
            emit DNSRecordDeleted(node, name, resource);
        } else {
            if (records[node][version][nameHash][resource].length == 0) {
                nameEntriesCount[node][version][nameHash]++;
            }
            records[node][version][nameHash][resource] = rrData;
            emit DNSRecordChanged(node, name, resource, rrData);
        }
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/profiles/InterfaceResolver.sol

pragma solidity >=0.8.4;



abstract contract InterfaceResolver is ResolverBase, AddrResolver {
    bytes4 constant private INTERFACE_INTERFACE_ID = bytes4(keccak256("interfaceImplementer(bytes32,bytes4)"));
    bytes4 private constant INTERFACE_META_ID = 0x01ffc9a7;

    event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer);

    mapping(bytes32=>mapping(bytes4=>address)) interfaces;

    /**
     * Sets an interface associated with a name.
     * Setting the address to 0 restores the default behaviour of querying the contract at `addr()` for interface support.
     * @param node The node to update.
     * @param interfaceID The EIP 165 interface ID.
     * @param implementer The address of a contract that implements this interface for this node.
     */
    function setInterface(bytes32 node, bytes4 interfaceID, address implementer) external authorised(node) {
        interfaces[node][interfaceID] = implementer;
        emit InterfaceChanged(node, interfaceID, implementer);
    }

    /**
     * Returns the address of a contract that implements the specified interface for this name.
     * If an implementer has not been set for this interfaceID and name, the resolver will query
     * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that
     * contract implements EIP165 and returns `true` for the specified interfaceID, its address
     * will be returned.
     * @param node The ENS node to query.
     * @param interfaceID The EIP 165 interface ID to check for.
     * @return The address that implements this interface, or 0 if the interface is unsupported.
     */
    function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address) {
        address implementer = interfaces[node][interfaceID];
        if(implementer != address(0)) {
            return implementer;
        }

        address a = addr(node);
        if(a == address(0)) {
            return address(0);
        }

        (bool success, bytes memory returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", INTERFACE_META_ID));
        if(!success || returnData.length < 32 || returnData[31] == 0) {
            // EIP 165 not supported by target
            return address(0);
        }

        (success, returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", interfaceID));
        if(!success || returnData.length < 32 || returnData[31] == 0) {
            // Specified interface not supported by target
            return address(0);
        }

        return a;
    }

    function supportsInterface(bytes4 interfaceID) virtual override(AddrResolver, ResolverBase) public pure returns(bool) {
        return interfaceID == INTERFACE_INTERFACE_ID || super.supportsInterface(interfaceID);
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/profiles/NameResolver.sol

pragma solidity >=0.8.4;


abstract contract NameResolver is ResolverBase {
    bytes4 constant private NAME_INTERFACE_ID = 0x691f3431;

    event NameChanged(bytes32 indexed node, string name);

    mapping(bytes32=>string) names;

    /**
     * Sets the name associated with an ENS node, for reverse records.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param name The name to set.
     */
    function setName(bytes32 node, string calldata name) external authorised(node) {
        names[node] = name;
        emit NameChanged(node, name);
    }

    /**
     * Returns the name associated with an ENS node, for reverse records.
     * Defined in EIP181.
     * @param node The ENS node to query.
     * @return The associated name.
     */
    function name(bytes32 node) external view returns (string memory) {
        return names[node];
    }

    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
        return interfaceID == NAME_INTERFACE_ID || super.supportsInterface(interfaceID);
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/profiles/PubkeyResolver.sol

pragma solidity >=0.8.4;


abstract contract PubkeyResolver is ResolverBase {
    bytes4 constant private PUBKEY_INTERFACE_ID = 0xc8690233;

    event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);

    struct PublicKey {
        bytes32 x;
        bytes32 y;
    }

    mapping(bytes32=>PublicKey) pubkeys;

    /**
     * Sets the SECP256k1 public key associated with an ENS node.
     * @param node The ENS node to query
     * @param x the X coordinate of the curve point for the public key.
     * @param y the Y coordinate of the curve point for the public key.
     */
    function setPubkey(bytes32 node, bytes32 x, bytes32 y) external authorised(node) {
        pubkeys[node] = PublicKey(x, y);
        emit PubkeyChanged(node, x, y);
    }

    /**
     * Returns the SECP256k1 public key associated with an ENS node.
     * Defined in EIP 619.
     * @param node The ENS node to query
     * @return x The X coordinate of the curve point for the public key.
     * @return y The Y coordinate of the curve point for the public key.
     */
    function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y) {
        return (pubkeys[node].x, pubkeys[node].y);
    }

    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
        return interfaceID == PUBKEY_INTERFACE_ID || super.supportsInterface(interfaceID);
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/profiles/TextResolver.sol

pragma solidity >=0.8.4;


abstract contract TextResolver is ResolverBase {
    bytes4 constant private TEXT_INTERFACE_ID = 0x59d1d43c;

    event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);

    mapping(bytes32=>mapping(string=>string)) texts;

    /**
     * Sets the text data associated with an ENS node and key.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param key The key to set.
     * @param value The text data value to set.
     */
    function setText(bytes32 node, string calldata key, string calldata value) external authorised(node) {
        texts[node][key] = value;
        emit TextChanged(node, key, key);
    }

    /**
     * Returns the text data associated with an ENS node and key.
     * @param node The ENS node to query.
     * @param key The text data key to query.
     * @return The associated text data.
     */
    function text(bytes32 node, string calldata key) external view returns (string memory) {
        return texts[node][key];
    }

    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {
        return interfaceID == TEXT_INTERFACE_ID || super.supportsInterface(interfaceID);
    }
}

// File: @ensdomains/ens-contracts/contracts/resolvers/PublicResolver.sol

pragma solidity >=0.8.4;










/**
 * A simple resolver anyone can use; only allows the owner of a node to set its
 * address.
 */
contract PublicResolver is ABIResolver, AddrResolver, ContentHashResolver, DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver {
    ENS ens;

    /**
     * A mapping of authorisations. An address that is authorised for a name
     * may make any changes to the name that the owner could, but may not update
     * the set of authorisations.
     * (node, owner, caller) => isAuthorised
     */
    mapping(bytes32=>mapping(address=>mapping(address=>bool))) public authorisations;

    event AuthorisationChanged(bytes32 indexed node, address indexed owner, address indexed target, bool isAuthorised);

    constructor(ENS _ens) {
        ens = _ens;
    }

    /**
     * @dev Sets or clears an authorisation.
     * Authorisations are specific to the caller. Any account can set an authorisation
     * for any name, but the authorisation that is checked will be that of the
     * current owner of a name. Thus, transferring a name effectively clears any
     * existing authorisations, and new authorisations can be set in advance of
     * an ownership transfer if desired.
     *
     * @param node The name to change the authorisation on.
     * @param target The address that is to be authorised or deauthorised.
     * @param isAuthorised True if the address should be authorised, or false if it should be deauthorised.
     */
    function setAuthorisation(bytes32 node, address target, bool isAuthorised) external {
        authorisations[node][msg.sender][target] = isAuthorised;
        emit AuthorisationChanged(node, msg.sender, target, isAuthorised);
    }

    function isAuthorised(bytes32 node) internal virtual override view returns(bool) {
        address owner = ens.owner(node);
        return owner == msg.sender || authorisations[node][owner][msg.sender];
    }

    function multicall(bytes[] calldata data) external returns(bytes[] memory results) {
        results = new bytes[](data.length);
        for(uint i = 0; i < data.length; i++) {
            (bool success, bytes memory result) = address(this).delegatecall(data[i]);
            require(success);
            results[i] = result;
        }
        return results;
    }

    function supportsInterface(bytes4 interfaceID) virtual override(ABIResolver, AddrResolver, ContentHashResolver, DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver) public pure returns(bool) {
        return super.supportsInterface(interfaceID);
    }
}

// File: contracts/roles/DomainNotifier.sol

pragma solidity 0.8.6;


/**
 * DomainNotifier is used as a central point from which to
 * determine which ENS domains (namespaces) have had their
 * resolved data updated
 */
contract DomainNotifier {
    event DomainUpdated(bytes32 indexed node);

    ENS _ens;

    constructor(ENS ens) {
        _ens = ens;
    }

    /**
     * Notifies of a domain/namespace's resolver data update.
     * Only the resolver that is set for a given node should
     * be able to trigger the notification
     */
    function domainUpdated(bytes32 node) external {
        address resolver = _ens.resolver(node);
        require(resolver == msg.sender);
        emit DomainUpdated(node);
    }
}

// File: contracts/roles/profiles/enrolment-conditions/EnrolmentPrerequisiteRolesResolver.sol

pragma solidity ^0.8.0;


/**
 * Profile for resolving roles which an identity must have to be eligible for a role claim
 */
abstract contract EnrolmentPrerequisiteRolesResolver is ResolverBase {
    bytes4 private constant PREREQUISITE_ROLES_INTERFACE_ID = 0xc986c404;

    struct PrerequisiteRoles {
        bytes32[] roles;
        bool mustHaveAll;
    }

    event PrerequisiteRolesChanged(
        bytes32 indexed node,
        PrerequisiteRoles newPrerequisiteRoles
    );

    mapping(bytes32 => PrerequisiteRoles) prerequisiteRolesMap;

    /**
     * Sets the prerequisite role required to be eligible for a role claim.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param roles The prerequisite roles to set.
     */
    function setPrerequisiteRoles(
        bytes32 node,
        bytes32[] calldata roles,
        bool mustHaveAll
    ) external authorised(node) {
        prerequisiteRolesMap[node] = PrerequisiteRoles(roles, mustHaveAll);
        emit PrerequisiteRolesChanged(node, prerequisiteRolesMap[node]);
    }

    /**
     * Returns the prerequisite roles required to be eligible for a role claim.
     * @param node The ENS node to query.
     * @return roles and whether or not the requester mustHaveAll roles
     */
    function prerequisiteRoles(bytes32 node)
        external
        view
        returns (bytes32[] memory roles, bool mustHaveAll)
    {
        return (
            prerequisiteRolesMap[node].roles,
            prerequisiteRolesMap[node].mustHaveAll
        );
    }

    function supportsInterface(bytes4 interfaceID)
        public
        pure
        virtual
        override
        returns (bool)
    {
        return
            interfaceID == PREREQUISITE_ROLES_INTERFACE_ID ||
            super.supportsInterface(interfaceID);
    }
}

// File: contracts/roles/profiles/issuance/IssuersResolver.sol

pragma solidity ^0.8.0;


/**
 * Profile for resolving identities (by did or by role) which can issue a role definition
 */
abstract contract IssuersResolver is ResolverBase {
    bytes4 private constant ISSUERS_INTERFACE_ID = 0xc53a4413;

    struct Issuers {
        address[] dids;
        bytes32 role;
    }

    event IssuersChanged(bytes32 indexed node, Issuers newIssuers);

    mapping(bytes32 => Issuers) issuersMap;

    /**
     * Sets the dids associated with a role.
     * Clears the role associated with a role.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param dids The dids to set.
     */
    function setIssuerDids(bytes32 node, address[] calldata dids)
        external
        authorised(node)
    {
        issuersMap[node].dids = dids;
        delete issuersMap[node].role;
        emit IssuersChanged(node, issuersMap[node]);
    }

    /**
     * Sets the dids associated with a role.
     * Clears the role associated with a role.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param role The role to set.
     */
    function setIssuerRole(bytes32 node, bytes32 role)
        external
        authorised(node)
    {
        issuersMap[node].role = role;
        delete issuersMap[node].dids;
        emit IssuersChanged(node, issuersMap[node]);
    }

    /**
     * Returns the issuers associated with an ENS node.
     * @param node The ENS node to query.
     * @return dids or role of eligible issuers.
     */
    function issuers(bytes32 node)
        external
        view
        returns (address[] memory dids, bytes32 role)
    {
        return (issuersMap[node].dids, issuersMap[node].role);
    }

    function supportsInterface(bytes4 interfaceID)
        public
        pure
        virtual
        override
        returns (bool)
    {
        return
            interfaceID == ISSUERS_INTERFACE_ID ||
            super.supportsInterface(interfaceID);
    }
}

// File: contracts/roles/profiles/issuance/IssuerTypeResolver.sol

pragma solidity ^0.8.0;


/**
 * Profile for resolving type of issuance expect for a role.
 * The types are mutually exclusive. A role can only have a single type at a time.
 * These possible types are:
 * 00: Approval by some identity (i.e. an identity from a list of DIDs, or an identity with a given role)
 * 10: “Real-time” approval by a smart contract.
 */
abstract contract IssuerTypeResolver is ResolverBase {
    bytes4 private constant ISSUER_TYPE_INTERFACE_ID = 0xc585f697;

    event IssuerTypeChanged(bytes32 indexed node, uint8 newType);

    // uint used instead of enum so that new types can be added with needing to update the resolver
    mapping(bytes32 => uint8) public issuerTypes;

    /**
     * Sets the issuerType associated with a role def.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param newIssuerType The issuerType to set.
     */
    function setIssuerType(bytes32 node, uint8 newIssuerType)
        external
        authorised(node)
    {
        issuerTypes[node] = newIssuerType;
        emit IssuerTypeChanged(node, issuerTypes[node]);
    }

    /**
     * Returns the issuerType associated with a role def.
     * @param node The ENS node to query.
     * @return The associated issuer type.
     */
    function issuerType(bytes32 node) external view returns (uint8) {
        return (issuerTypes[node]);
    }

    function supportsInterface(bytes4 interfaceID)
        public
        pure
        virtual
        override
        returns (bool)
    {
        return
            interfaceID == ISSUER_TYPE_INTERFACE_ID ||
            super.supportsInterface(interfaceID);
    }
}

// File: contracts/roles/profiles/revocation/RevokersResolver.sol

pragma solidity ^0.8.0;


/**
 * Profile for resolving identities (by did or by role) which can revoke a role definition
 */
abstract contract RevokersResolver is ResolverBase {
    bytes4 private constant REVOKERS_INTERFACE_ID = 0x74d3013a;

    struct Revokers {
        address[] dids;
        bytes32 role;
    }

    event RevokersChanged(bytes32 indexed node, Revokers newRevokers);

    mapping(bytes32 => Revokers) revokersMap;

    /**
     * Sets the dids associated with a role.
     * Clears the role associated with a role.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param dids The dids to set.
     */
    function setRevokerDids(bytes32 node, address[] calldata dids)
        external
        authorised(node)
    {
        revokersMap[node].dids = dids;
        delete revokersMap[node].role;
        emit RevokersChanged(node, revokersMap[node]);
    }

    /**
     * Sets the dids associated with a role.
     * Clears the role associated with a role.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param role The role to set.
     */
    function setRevokerRole(bytes32 node, bytes32 role)
        external
        authorised(node)
    {
        revokersMap[node].role = role;
        delete revokersMap[node].dids;
        emit RevokersChanged(node, revokersMap[node]);
    }

    /**
     * Returns the revokers associated with an ENS node.
     * @param node The ENS node to query.
     * @return dids or role of eligible revokers.
     */
    function revokers(bytes32 node)
        external
        view
        returns (address[] memory dids, bytes32 role)
    {
        return (revokersMap[node].dids, revokersMap[node].role);
    }

    function supportsInterface(bytes4 interfaceID)
        public
        pure
        virtual
        override
        returns (bool)
    {
        return
            interfaceID == REVOKERS_INTERFACE_ID ||
            super.supportsInterface(interfaceID);
    }
}

// File: contracts/roles/profiles/revocation/RevokerTypeResolver.sol

pragma solidity ^0.8.0;


/**
 * Profile for resolving type of revocation expect for a role.
 * The types are mutually exclusive. A role can only have a single type at a time.
 * These possible types are:
 * 00: Revocations allowed for some identity (i.e. an identity from a list of DIDs, or an identity with a given role)
 * 10: “Real-time” revocation by a smart contract.
 */
abstract contract RevokerTypeResolver is ResolverBase {
    bytes4 private constant REVOKER_TYPE_INTERFACE_ID = 0xec7adf27;

    event RevokerTypeChanged(bytes32 indexed node, uint8 newType);

    // uint used instead of enum so that new types can be added without needing to update the resolver
    mapping(bytes32 => uint8) public revokerTypes;

    /**
     * Sets the revokerType associated with a role def.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param newRevokerType The revokerType to set.
     */
    function setRevokerType(bytes32 node, uint8 newRevokerType)
        external
        authorised(node)
    {
        revokerTypes[node] = newRevokerType;
        emit RevokerTypeChanged(node, revokerTypes[node]);
    }

    /**
     * Returns the revokerType associated with a role def.
     * @param node The ENS node to query.
     * @return The associated revoker type.
     */
    function revokerType(bytes32 node) external view returns (uint8) {
        return (revokerTypes[node]);
    }

    function supportsInterface(bytes4 interfaceID)
        public
        pure
        virtual
        override
        returns (bool)
    {
        return
            interfaceID == REVOKER_TYPE_INTERFACE_ID ||
            super.supportsInterface(interfaceID);
    }
}

// File: contracts/roles/profiles/VersionNumberResolver.sol

pragma solidity ^0.8.0;


/**
 * Profile for resolving version number of role definition.
 */
abstract contract VersionNumberResolver is ResolverBase {
    bytes4 private constant VERSION_NUMBER_INTERFACE_ID = 0x338bc8fa;

    event VersionNumberChanged(bytes32 indexed node, uint256 newVersion);

    mapping(bytes32 => uint256) public versionNumbers;

    /**
     * Sets the version number associated with a role def.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param newVersionNumber The versionNumber to set.
     */
    function setVersionNumber(bytes32 node, uint256 newVersionNumber)
        external
        authorised(node)
    {
        versionNumbers[node] = newVersionNumber;
        emit VersionNumberChanged(node, versionNumbers[node]);
    }

    /**
     * Returns the version number associated with a role def.
     * @param node The ENS node to query.
     * @return The associated version number.
     */
    function versionNumber(bytes32 node) external view returns (uint256) {
        return (versionNumbers[node]);
    }

    function supportsInterface(bytes4 interfaceID)
        public
        pure
        virtual
        override
        returns (bool)
    {
        return
            interfaceID == VERSION_NUMBER_INTERFACE_ID ||
            super.supportsInterface(interfaceID);
    }
}

// File: contracts/roles/RoleDefinitionResolverV2.sol

// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.6;

/**
 * An extension of the PublicResolver customized for RoleDefinitions
 */
contract RoleDefinitionResolverV2 is
    PublicResolver,
    VersionNumberResolver,
    IssuerTypeResolver,
    IssuersResolver,
    RevokerTypeResolver,
    RevokersResolver,
    EnrolmentPrerequisiteRolesResolver
{
    bytes4 private constant DOMAIN_UPDATED_INTERFACE_ID = 0x61610164;

    DomainNotifier private notifier;

    constructor(ENS _ens, DomainNotifier _notifier) PublicResolver(_ens) {
        notifier = _notifier;
    }

    function isAuthorised(bytes32 node)
        internal
        view
        override(PublicResolver, ResolverBase)
        returns (bool)
    {
        address owner = ens.owner(node);
        return
            owner == msg.sender ||
            authorisations[node][owner][msg.sender] ||
            ens.isApprovedForAll(owner, msg.sender);
    }

    function domainUpdated(bytes32 node) external authorised(node) {
        notifier.domainUpdated(node);
    }

    function supportsInterface(bytes4 interfaceID)
        public
        pure
        override(
            PublicResolver,
            VersionNumberResolver,
            IssuerTypeResolver,
            IssuersResolver,
            RevokerTypeResolver,
            RevokersResolver,
            EnrolmentPrerequisiteRolesResolver
        )
        returns (bool)
    {
        return
            interfaceID == DOMAIN_UPDATED_INTERFACE_ID ||
            super.supportsInterface(interfaceID);
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_ens","internalType":"contract ENS"},{"type":"address","name":"_notifier","internalType":"contract DomainNotifier"}]},{"type":"event","name":"ABIChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"uint256","name":"contentType","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"AddrChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"address","name":"a","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"AddressChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"uint256","name":"coinType","internalType":"uint256","indexed":false},{"type":"bytes","name":"newAddress","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"AuthorisationChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"target","internalType":"address","indexed":true},{"type":"bool","name":"isAuthorised","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"ContenthashChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"bytes","name":"hash","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"DNSRecordChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"bytes","name":"name","internalType":"bytes","indexed":false},{"type":"uint16","name":"resource","internalType":"uint16","indexed":false},{"type":"bytes","name":"record","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"DNSRecordDeleted","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"bytes","name":"name","internalType":"bytes","indexed":false},{"type":"uint16","name":"resource","internalType":"uint16","indexed":false}],"anonymous":false},{"type":"event","name":"DNSZoneCleared","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"DNSZonehashChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"bytes","name":"lastzonehash","internalType":"bytes","indexed":false},{"type":"bytes","name":"zonehash","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"InterfaceChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"bytes4","name":"interfaceID","internalType":"bytes4","indexed":true},{"type":"address","name":"implementer","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"IssuerTypeChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"uint8","name":"newType","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"IssuersChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"tuple","name":"newIssuers","internalType":"struct IssuersResolver.Issuers","indexed":false,"components":[{"type":"address[]","name":"dids","internalType":"address[]"},{"type":"bytes32","name":"role","internalType":"bytes32"}]}],"anonymous":false},{"type":"event","name":"NameChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"string","name":"name","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"PrerequisiteRolesChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"tuple","name":"newPrerequisiteRoles","internalType":"struct EnrolmentPrerequisiteRolesResolver.PrerequisiteRoles","indexed":false,"components":[{"type":"bytes32[]","name":"roles","internalType":"bytes32[]"},{"type":"bool","name":"mustHaveAll","internalType":"bool"}]}],"anonymous":false},{"type":"event","name":"PubkeyChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"x","internalType":"bytes32","indexed":false},{"type":"bytes32","name":"y","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"RevokerTypeChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"uint8","name":"newType","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"RevokersChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"tuple","name":"newRevokers","internalType":"struct RevokersResolver.Revokers","indexed":false,"components":[{"type":"address[]","name":"dids","internalType":"address[]"},{"type":"bytes32","name":"role","internalType":"bytes32"}]}],"anonymous":false},{"type":"event","name":"TextChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"string","name":"indexedKey","internalType":"string","indexed":true},{"type":"string","name":"key","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"VersionNumberChanged","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32","indexed":true},{"type":"uint256","name":"newVersion","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"bytes","name":"","internalType":"bytes"}],"name":"ABI","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"uint256","name":"contentTypes","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"addr","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"addr","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"uint256","name":"coinType","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"authorisations","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"},{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"clearDNSZone","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"contenthash","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"dnsRecord","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes32","name":"name","internalType":"bytes32"},{"type":"uint16","name":"resource","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"domainUpdated","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasDNSRecords","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes32","name":"name","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"interfaceImplementer","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes4","name":"interfaceID","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"issuerType","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"issuerTypes","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"dids","internalType":"address[]"},{"type":"bytes32","name":"role","internalType":"bytes32"}],"name":"issuers","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes[]","name":"results","internalType":"bytes[]"}],"name":"multicall","inputs":[{"type":"bytes[]","name":"data","internalType":"bytes[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32[]","name":"roles","internalType":"bytes32[]"},{"type":"bool","name":"mustHaveAll","internalType":"bool"}],"name":"prerequisiteRoles","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"x","internalType":"bytes32"},{"type":"bytes32","name":"y","internalType":"bytes32"}],"name":"pubkey","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"revokerType","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"revokerTypes","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"dids","internalType":"address[]"},{"type":"bytes32","name":"role","internalType":"bytes32"}],"name":"revokers","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setABI","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"uint256","name":"contentType","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAddr","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"uint256","name":"coinType","internalType":"uint256"},{"type":"bytes","name":"a","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAddr","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"address","name":"a","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAuthorisation","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"address","name":"target","internalType":"address"},{"type":"bool","name":"isAuthorised","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setContenthash","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes","name":"hash","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDNSRecords","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setInterface","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes4","name":"interfaceID","internalType":"bytes4"},{"type":"address","name":"implementer","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setIssuerDids","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"address[]","name":"dids","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setIssuerRole","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setIssuerType","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"uint8","name":"newIssuerType","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setName","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"string","name":"name","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPrerequisiteRoles","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes32[]","name":"roles","internalType":"bytes32[]"},{"type":"bool","name":"mustHaveAll","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPubkey","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes32","name":"x","internalType":"bytes32"},{"type":"bytes32","name":"y","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRevokerDids","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"address[]","name":"dids","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRevokerRole","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRevokerType","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"uint8","name":"newRevokerType","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setText","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"string","name":"key","internalType":"string"},{"type":"string","name":"value","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setVersionNumber","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"uint256","name":"newVersionNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setZonehash","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"bytes","name":"hash","internalType":"bytes"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceID","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"text","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"},{"type":"string","name":"key","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"versionNumber","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"versionNumbers","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"zonehash","inputs":[{"type":"bytes32","name":"node","internalType":"bytes32"}]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106102745760003560e01c80637737221311610151578063c585f697116100c3578063d5fa2b0011610087578063d5fa2b0014610822578063e59d895d1461083e578063ec7adf271461085a578063f1bed5851461088a578063f1cb7e06146108ba578063f86bc879146108ea57610274565b8063c585f69714610744578063c869023314610774578063c986c404146107a5578063ce3decdc146107d6578063d055e4f8146107f257610274565b8063ac9650d811610115578063ac9650d81461065f578063ad154c691461068f578063ad5780af146106ab578063bad72cbe146106c7578063bc1c58d1146106e3578063c53a44131461071357610274565b806377372213146105bf5780638b95dd71146105db578063916b848a146105f7578063a8fa568214610613578063abc52d5e1461064357610274565b806349a762a7116101ea5780635c98042b116101ae5780635c98042b146104da578063616101641461050a578063623195b014610526578063658d7dad14610542578063691f34311461055e57806374d3013a1461058e57610274565b806349a762a7146104125780634cbf6ba41461042e5780635146bd641461045e57806355329f3f1461048e57806359d1d43c146104aa57610274565b806329cd62ea1161023c57806329cd62ea14610342578063304e6ade1461035e578063338bc8fa1461037a5780633393d53c146103aa5780633b3b57de146103c65780633e9ce794146103f657610274565b806301ffc9a7146102795780630af179d7146102a957806310f13a8c146102c5578063124a319c146102e15780632203ab5614610311575b600080fd5b610293600480360381019061028e919061458b565b61091a565b6040516102a09190614c4b565b60405180910390f35b6102c360048036038101906102be91906142d3565b61097b565b005b6102df60048036038101906102da9190614393565b610bad565b005b6102fb60048036038101906102f69190614240565b610c5b565b6040516103089190614b4f565b60405180910390f35b61032b60048036038101906103269190614428565b611053565b604051610339929190614e80565b60405180910390f35b61035c6004803603810190610357919061419a565b611187565b005b610378600480360381019061037391906142d3565b611219565b005b610394600480360381019061038f9190613f73565b61128f565b6040516103a19190614e65565b60405180910390f35b6103c460048036038101906103bf919061454b565b6112ac565b005b6103e060048036038101906103db9190613f73565b611348565b6040516103ed9190614b85565b60405180910390f35b610410600480360381019061040b9190614033565b61137e565b005b61042c6004803603810190610427919061415a565b61148e565b005b6104486004803603810190610443919061415a565b61152d565b6040516104559190614c4b565b60405180910390f35b61047860048036038101906104739190613f73565b611595565b6040516104859190614e65565b60405180910390f35b6104a860048036038101906104a3919061454b565b6115ad565b005b6104c460048036038101906104bf9190614333565b611649565b6040516104d19190614ddd565b60405180910390f35b6104f460048036038101906104ef9190613f73565b61170e565b6040516105019190614ce9565b60405180910390f35b610524600480360381019061051f9190613f73565b6117b3565b005b610540600480360381019061053b9190614468565b611857565b005b61055c60048036038101906105579190614086565b6118ed565b005b61057860048036038101906105739190613f73565b611990565b6040516105859190614ddd565b60405180910390f35b6105a860048036038101906105a39190613f73565b611a35565b6040516105b6929190614bc9565b60405180910390f35b6105d960048036038101906105d49190614333565b611af7565b005b6105f560048036038101906105f091906144dc565b611b6d565b005b610611600480360381019061060c919061415a565b611c43565b005b61062d600480360381019061062891906141ed565b611ce2565b60405161063a9190614ce9565b60405180910390f35b61065d600480360381019061065891906140e6565b611dd7565b005b61067960048036038101906106749190613ef9565b611ee6565b6040516106869190614c29565b60405180910390f35b6106a960048036038101906106a49190614428565b612020565b005b6106c560048036038101906106c09190613f73565b61209b565b005b6106e160048036038101906106dc9190614086565b612108565b005b6106fd60048036038101906106f89190613f73565b6121ab565b60405161070a9190614ce9565b60405180910390f35b61072d60048036038101906107289190613f73565b612250565b60405161073b929190614bc9565b60405180910390f35b61075e60048036038101906107599190613f73565b612312565b60405161076b9190614eb0565b60405180910390f35b61078e60048036038101906107899190613f73565b61233c565b60405161079c929190614c81565b60405180910390f35b6107bf60048036038101906107ba9190613f73565b612376565b6040516107cd929190614bf9565b60405180910390f35b6107f060048036038101906107eb91906142d3565b61240f565b005b61080c60048036038101906108079190613f73565b612528565b6040516108199190614eb0565b60405180910390f35b61083c60048036038101906108379190613fa0565b612548565b005b61085860048036038101906108539190614280565b612574565b005b610874600480360381019061086f9190613f73565b612686565b6040516108819190614eb0565b60405180910390f35b6108a4600480360381019061089f9190613f73565b6126b0565b6040516108b19190614eb0565b60405180910390f35b6108d460048036038101906108cf9190614428565b6126d0565b6040516108e19190614ce9565b60405180910390f35b61090460048036038101906108ff9190613fe0565b612787565b6040516109119190614c4b565b60405180910390f35b6000636161016460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109745750610973826127c3565b5b9050919050565b8261098581612824565b61098e57600080fd5b6000806060806000806109ef60008a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612a6190919063ffffffff16565b90505b6109fb81612a8b565b610b315760008661ffff161415610a575780604001519550610a1c81612aa1565b935083604051602001610a2f9190614b1f565b604051602081830303815290604052805190602001209150610a5081612ad8565b9250610b23565b6000610a6282612aa1565b9050816040015161ffff168761ffff16141580610a8f5750610a8d8186612b1190919063ffffffff16565b155b15610b2157610afa8b86898d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508a8b8860200151610af09190615160565b60008b5114612b38565b816040015196508160200151955080945084805190602001209250610b1e82612ad8565b93505b505b610b2c81612e63565b6109f2565b50600083511115610ba257610ba18984878b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505088898e8e9050610b979190615160565b6000895114612b38565b5b505050505050505050565b84610bb781612824565b610bc057600080fd5b8282600a60008981526020019081526020016000208787604051610be5929190614b36565b90815260200160405180910390209190610c0092919061388c565b508484604051610c11929190614b36565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a75508787604051610c4b929190614db9565b60405180910390a3505050505050565b600080600760008581526020019081526020016000206000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d20578091505061104d565b6000610d2b85611348565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d6d5760009250505061104d565b6000808273ffffffffffffffffffffffffffffffffffffffff166301ffc9a760e01b604051602401610d9f9190614caa565b6040516020818303038152906040527f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610e299190614b1f565b600060405180830381855afa9150503d8060008114610e64576040519150601f19603f3d011682016040523d82523d6000602084013e610e69565b606091505b5091509150811580610e7c575060208151105b80610eca5750600060f81b81601f81518110610e9b57610e9a6154ca565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15610edc57600094505050505061104d565b8273ffffffffffffffffffffffffffffffffffffffff1686604051602401610f049190614caa565b6040516020818303038152906040527f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610f8e9190614b1f565b600060405180830381855afa9150503d8060008114610fc9576040519150601f19603f3d011682016040523d82523d6000602084013e610fce565b606091505b508092508193505050811580610fe5575060208151105b806110335750600060f81b81601f81518110611004576110036154ca565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b1561104557600094505050505061104d565b829450505050505b92915050565b60006060600080600086815260200190815260200160002090506000600190505b848111611167576000858216141580156110ac5750600082600083815260200190815260200160002080546110a890615318565b9050115b1561115b57808260008381526020019081526020016000208080546110d090615318565b80601f01602080910402602001604051908101604052809291908181526020018280546110fc90615318565b80156111495780601f1061111e57610100808354040283529160200191611149565b820191906000526020600020905b81548152906001019060200180831161112c57829003601f168201915b50505050509050935093505050611180565b600181901b9050611074565b5060006040518060200160405280600081525092509250505b9250929050565b8261119181612824565b61119a57600080fd5b604051806040016040528084815260200183815250600960008681526020019081526020016000206000820151816000015560208201518160010155905050837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46848460405161120b929190614c81565b60405180910390a250505050565b8261122381612824565b61122c57600080fd5b828260026000878152602001908152602001600020919061124e929190613912565b50837fe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d75788484604051611281929190614cc5565b60405180910390a250505050565b6000600d6000838152602001908152602001600020549050919050565b816112b681612824565b6112bf57600080fd5b816010600085815260200190815260200160002060006101000a81548160ff021916908360ff160217905550827fb171544f546e8605a60c7cfbf3d2b6a808a2089ae865c93d983d9e26a8f362526010600086815260200190815260200160002060009054906101000a900460ff1660405161133b9190614eb0565b60405180910390a2505050565b60008061135683603c6126d0565b905060008151141561136c576000915050611379565b61137581612fad565b9150505b919050565b80600c600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16847fe1c5610a6e0cbe10764ecd182adcef1ec338dc4e199c99c32ce98f38e12791df846040516114819190614c4b565b60405180910390a4505050565b8161149881612824565b6114a157600080fd5b8160116000858152602001908152602001600020600101819055506011600084815260200190815260200160002060000160006114de9190613998565b827fe63737c75876c3e30f959222eccba9bd21a79e44ebbdeba938a2310016d14ded601160008681526020019081526020016000206040516115209190614e43565b60405180910390a2505050565b60008060066000858152602001908152602001600020600060046000878152602001908152602001600020548152602001908152602001600020600084815260200190815260200160002060009054906101000a900461ffff1661ffff161415905092915050565b600d6020528060005260406000206000915090505481565b816115b781612824565b6115c057600080fd5b81600e600085815260200190815260200160002060006101000a81548160ff021916908360ff160217905550827f7fc5f6d56736f6859a63066a1e8f557dc0b34a3a0af625f99db5a258963399d3600e600086815260200190815260200160002060009054906101000a900460ff1660405161163c9190614eb0565b60405180910390a2505050565b6060600a6000858152602001908152602001600020838360405161166e929190614b36565b9081526020016040518091039020805461168790615318565b80601f01602080910402602001604051908101604052809291908181526020018280546116b390615318565b80156117005780601f106116d557610100808354040283529160200191611700565b820191906000526020600020905b8154815290600101906020018083116116e357829003601f168201915b505050505090509392505050565b606060036000838152602001908152602001600020805461172e90615318565b80601f016020809104026020016040519081016040528092919081815260200182805461175a90615318565b80156117a75780601f1061177c576101008083540402835291602001916117a7565b820191906000526020600020905b81548152906001019060200180831161178a57829003601f168201915b50505050509050919050565b806117bd81612824565b6117c657600080fd5b601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166361610164836040518263ffffffff1660e01b81526004016118219190614c66565b600060405180830381600087803b15801561183b57600080fd5b505af115801561184f573d6000803e3d6000fd5b505050505050565b8361186181612824565b61186a57600080fd5b60008460018661187a9190615160565b161461188557600080fd5b8282600080888152602001908152602001600020600087815260200190815260200160002091906118b7929190613912565b5083857faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe360405160405180910390a35050505050565b826118f781612824565b61190057600080fd5b82826011600087815260200190815260200160002060000191906119259291906139b9565b506011600085815260200190815260200160002060010160009055837fe63737c75876c3e30f959222eccba9bd21a79e44ebbdeba938a2310016d14ded601160008781526020019081526020016000206040516119829190614e43565b60405180910390a250505050565b60606008600083815260200190815260200160002080546119b090615318565b80601f01602080910402602001604051908101604052809291908181526020018280546119dc90615318565b8015611a295780601f106119fe57610100808354040283529160200191611a29565b820191906000526020600020905b815481529060010190602001808311611a0c57829003601f168201915b50505050509050919050565b6060600060116000848152602001908152602001600020600001601160008581526020019081526020016000206001015481805480602002602001604051908101604052809291908181526020018280548015611ae757602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611a9d575b5050505050915091509150915091565b82611b0181612824565b611b0a57600080fd5b8282600860008781526020019081526020016000209190611b2c92919061388c565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051611b5f929190614db9565b60405180910390a250505050565b82611b7781612824565b611b8057600080fd5b837f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af7528484604051611bb2929190614e80565b60405180910390a2603c831415611c0457837f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2611bee84612fad565b604051611bfb9190614b6a565b60405180910390a25b816001600086815260200190815260200160002060008581526020019081526020016000209080519060200190611c3c929190613a59565b5050505050565b81611c4d81612824565b611c5657600080fd5b81600f600085815260200190815260200160002060010181905550600f60008481526020019081526020016000206000016000611c939190613998565b827fab0ef04b258ea77c9247dad5b03ada5b2ed5b370f62963b9f84bd9066d499e5c600f6000868152602001908152602001600020604051611cd59190614dff565b60405180910390a2505050565b606060056000858152602001908152602001600020600060046000878152602001908152602001600020548152602001908152602001600020600084815260200190815260200160002060008361ffff1661ffff1681526020019081526020016000208054611d5090615318565b80601f0160208091040260200160405190810160405280929190818152602001828054611d7c90615318565b8015611dc95780601f10611d9e57610100808354040283529160200191611dc9565b820191906000526020600020905b815481529060010190602001808311611dac57829003601f168201915b505050505090509392505050565b83611de181612824565b611dea57600080fd5b6040518060400160405280858580806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508152602001831515815250601260008781526020019081526020016000206000820151816000019080519060200190611e71929190613adf565b5060208201518160010160006101000a81548160ff021916908315150217905550905050847f26c1ae1a8943085479d1599dd3884c06f33c62627d918463e96a9b4e519894a360126000888152602001908152602001600020604051611ed79190614e21565b60405180910390a25050505050565b60608282905067ffffffffffffffff811115611f0557611f046154f9565b5b604051908082528060200260200182016040528015611f3857816020015b6060815260200190600190039081611f235790505b50905060005b83839050811015612019576000803073ffffffffffffffffffffffffffffffffffffffff16868685818110611f7657611f756154ca565b5b9050602002810190611f889190614ecb565b604051611f96929190614b06565b600060405180830381855af49150503d8060008114611fd1576040519150601f19603f3d011682016040523d82523d6000602084013e611fd6565b606091505b509150915081611fe557600080fd5b80848481518110611ff957611ff86154ca565b5b602002602001018190525050508080612011906153f4565b915050611f3e565b5092915050565b8161202a81612824565b61203357600080fd5b81600d600085815260200190815260200160002081905550827f85d51b785b03277eec6a168d133b8cffc1ab9f99d3e6a1b4061c23841801698f600d60008681526020019081526020016000205460405161208e9190614e65565b60405180910390a2505050565b806120a581612824565b6120ae57600080fd5b6004600083815260200190815260200160002060008154809291906120d2906153f4565b9190505550817fb757169b8492ca2f1c6619d9d76ce22803035c3b1d5f6930dffe7b127c1a198360405160405180910390a25050565b8261211281612824565b61211b57600080fd5b8282600f600087815260200190815260200160002060000191906121409291906139b9565b50600f600085815260200190815260200160002060010160009055837fab0ef04b258ea77c9247dad5b03ada5b2ed5b370f62963b9f84bd9066d499e5c600f600087815260200190815260200160002060405161219d9190614dff565b60405180910390a250505050565b60606002600083815260200190815260200160002080546121cb90615318565b80601f01602080910402602001604051908101604052809291908181526020018280546121f790615318565b80156122445780601f1061221957610100808354040283529160200191612244565b820191906000526020600020905b81548152906001019060200180831161222757829003601f168201915b50505050509050919050565b60606000600f6000848152602001908152602001600020600001600f6000858152602001908152602001600020600101548180548060200260200160405190810160405280929190818152602001828054801561230257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116122b8575b5050505050915091509150915091565b6000600e600083815260200190815260200160002060009054906101000a900460ff169050919050565b6000806009600084815260200190815260200160002060000154600960008581526020019081526020016000206001015491509150915091565b60606000601260008481526020019081526020016000206000016012600085815260200190815260200160002060010160009054906101000a900460ff16818054806020026020016040519081016040528092919081815260200182805480156123ff57602002820191906000526020600020905b8154815260200190600101908083116123eb575b5050505050915091509150915091565b8261241981612824565b61242257600080fd5b600060036000868152602001908152602001600020805461244290615318565b80601f016020809104026020016040519081016040528092919081815260200182805461246e90615318565b80156124bb5780601f10612490576101008083540402835291602001916124bb565b820191906000526020600020905b81548152906001019060200180831161249e57829003601f168201915b5050505050905083836003600088815260200190815260200160002091906124e4929190613912565b50847f8f15ed4b723ef428f250961da8315675b507046737e19319fc1a4d81bfe87f8582868660405161251993929190614d0b565b60405180910390a25050505050565b600e6020528060005260406000206000915054906101000a900460ff1681565b8161255281612824565b61255b57600080fd5b61256f83603c61256a85612fd0565b611b6d565b505050565b8261257e81612824565b61258757600080fd5b81600760008681526020019081526020016000206000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916847f7c69f06bea0bdef565b709e93a147836b0063ba2dd89f02d0b7e8d931e6a6daa846040516126789190614b4f565b60405180910390a350505050565b60006010600083815260200190815260200160002060009054906101000a900460ff169050919050565b60106020528060005260406000206000915054906101000a900460ff1681565b6060600160008481526020019081526020016000206000838152602001908152602001600020805461270190615318565b80601f016020809104026020016040519081016040528092919081815260200182805461272d90615318565b801561277a5780601f1061274f5761010080835404028352916020019161277a565b820191906000526020600020905b81548152906001019060200180831161275d57829003601f168201915b5050505050905092915050565b600c602052826000526040600020602052816000526040600020602052806000526040600020600092509250509054906101000a900460ff1681565b600063c986c40460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061281d575061281c82613034565b5b9050919050565b600080600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3846040518263ffffffff1660e01b81526004016128829190614c66565b60206040518083038186803b15801561289a57600080fd5b505afa1580156128ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128d29190613ecc565b90503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806129a55750600c600084815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b80612a595750600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e985e9c582336040518363ffffffff1660e01b8152600401612a08929190614ba0565b60206040518083038186803b158015612a2057600080fd5b505afa158015612a34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a589190613f46565b5b915050919050565b612a69613b2c565b828160000181905250818160c0018181525050612a8581612e63565b92915050565b6000816000015151826020015110159050919050565b6060612ad18260200151612abd84600001518560200151613095565b84600001516131129092919063ffffffff16565b9050919050565b6060612b0a8260a001518360a001518460c00151612af69190615160565b84600001516131129092919063ffffffff16565b9050919050565b600081518351148015612b305750612b2f83600084600087516131a7565b5b905092915050565b6000600460008981526020019081526020016000205490506000878051906020012090506000612b738686896131129092919063ffffffff16565b90508315612ce5576000600560008c81526020019081526020016000206000858152602001908152602001600020600084815260200190815260200160002060008a61ffff1661ffff1681526020019081526020016000208054612bd690615318565b905014612c4c57600660008b815260200190815260200160002060008481526020019081526020016000206000838152602001908152602001600020600081819054906101000a900461ffff1680929190612c30906152ee565b91906101000a81548161ffff021916908361ffff160217905550505b600560008b81526020019081526020016000206000848152602001908152602001600020600083815260200190815260200160002060008961ffff1661ffff1681526020019081526020016000206000612ca69190613b77565b897f03528ed0c2a3ebc993b12ce3c16bb382f9c7d88ef7d8a1bf290eaf35955a12078a8a604051612cd8929190614d44565b60405180910390a2612e57565b6000600560008c81526020019081526020016000206000858152602001908152602001600020600084815260200190815260200160002060008a61ffff1661ffff1681526020019081526020016000208054612d4090615318565b90501415612db757600660008b815260200190815260200160002060008481526020019081526020016000206000838152602001908152602001600020600081819054906101000a900461ffff1680929190612d9b906153c9565b91906101000a81548161ffff021916908361ffff160217905550505b80600560008c81526020019081526020016000206000858152602001908152602001600020600084815260200190815260200160002060008a61ffff1661ffff1681526020019081526020016000209080519060200190612e19929190613a59565b50897f52a608b3303a48862d07a73d82fa221318c0027fbbcfb1b2329bface3f19ff2b8a8a84604051612e4e93929190614d74565b60405180910390a25b50505050505050505050565b8060c00151816020018181525050806000015151816020015110612e8657612faa565b6000612e9a82600001518360200151613095565b8260200151612ea9919061510a565b9050612ec28183600001516131cb90919063ffffffff16565b826040019061ffff16908161ffff1681525050600281612ee2919061510a565b9050612efb8183600001516131cb90919063ffffffff16565b826060019061ffff16908161ffff1681525050600281612f1b919061510a565b9050612f348183600001516131fa90919063ffffffff16565b826080019063ffffffff16908163ffffffff1681525050600481612f58919061510a565b90506000612f738284600001516131cb90919063ffffffff16565b61ffff169050600282612f86919061510a565b9150818360a00181815250508082612f9e919061510a565b8360c001818152505050505b50565b60006014825114612fbd57600080fd5b600c6101000a6020830151049050919050565b6060601467ffffffffffffffff811115612fed57612fec6154f9565b5b6040519080825280601f01601f19166020018201604052801561301f5781602001600182028036833780820191505090505b509050600c6101000a82026020820152919050565b60006374d3013a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061308e575061308d8261322b565b5b9050919050565b6000808290505b6001156130fd57835181106130b4576130b361543d565b5b60006130c9828661328c90919063ffffffff16565b60ff1690506001816130db919061510a565b826130e6919061510a565b915060008114156130f757506130fd565b5061309c565b82816131099190615160565b91505092915050565b606083518284613122919061510a565b111561312d57600080fd5b60008267ffffffffffffffff811115613149576131486154f9565b5b6040519080825280601f01601f19166020018201604052801561317b5781602001600182028036833780820191505090505b509050600080602083019150856020880101905061319a8282876132b7565b8293505050509392505050565b60006131b484848461331b565b6131bf87878561331b565b14905095945050505050565b600082516002836131dc919061510a565b11156131e757600080fd5b61ffff8260028501015116905092915050565b6000825160048361320b919061510a565b111561321657600080fd5b63ffffffff8260048501015116905092915050565b600063ec7adf2760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613285575061328482613347565b5b9050919050565b60008282815181106132a1576132a06154ca565b5b602001015160f81c60f81b60f81c905092915050565b5b602081106132f657815183526020836132d1919061510a565b92506020826132e0919061510a565b91506020816132ef9190615160565b90506132b8565b60006001826020036101000a0390508019835116818551168181178652505050505050565b60008351828461332b919061510a565b111561333657600080fd5b818360208601012090509392505050565b600063c53a441360e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806133a157506133a0826133a8565b5b9050919050565b600063c585f69760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613402575061340182613409565b5b9050919050565b600063338bc8fa60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061346357506134628261346a565b5b9050919050565b60006134758261347c565b9050919050565b60006359d1d43c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806134d657506134d5826134dd565b5b9050919050565b600063c869023360e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061353757506135368261353e565b5b9050919050565b600063691f343160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061359857506135978261359f565b5b9050919050565b60007f124a319c1247f4318c3c16c7e9cc865d0fb5d80d7bf02f56cafc0d14da0208507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613612575061361182613619565b5b9050919050565b600063a8fa568260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806136b25750635c47637c60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806136c257506136c1826136c9565b5b9050919050565b600063bc1c58d160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061372357506137228261372a565b5b9050919050565b6000633b3b57de60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806137c3575063f1cb7e0660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806137d357506137d2826137da565b5b9050919050565b6000632203ab5660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061383457506138338261383b565b5b9050919050565b60006301ffc9a760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b82805461389890615318565b90600052602060002090601f0160209004810192826138ba5760008555613901565b82601f106138d357803560ff1916838001178555613901565b82800160010185558215613901579182015b828111156139005782358255916020019190600101906138e5565b5b50905061390e9190613bb7565b5090565b82805461391e90615318565b90600052602060002090601f0160209004810192826139405760008555613987565b82601f1061395957803560ff1916838001178555613987565b82800160010185558215613987579182015b8281111561398657823582559160200191906001019061396b565b5b5090506139949190613bb7565b5090565b50805460008255906000526020600020908101906139b69190613bb7565b50565b828054828255906000526020600020908101928215613a48579160200282015b82811115613a4757823573ffffffffffffffffffffffffffffffffffffffff168260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550916020019190600101906139d9565b5b509050613a559190613bb7565b5090565b828054613a6590615318565b90600052602060002090601f016020900481019282613a875760008555613ace565b82601f10613aa057805160ff1916838001178555613ace565b82800160010185558215613ace579182015b82811115613acd578251825591602001919060010190613ab2565b5b509050613adb9190613bb7565b5090565b828054828255906000526020600020908101928215613b1b579160200282015b82811115613b1a578251825591602001919060010190613aff565b5b509050613b289190613bd4565b5090565b6040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b508054613b8390615318565b6000825580601f10613b955750613bb4565b601f016020900490600052602060002090810190613bb39190613bb7565b5b50565b5b80821115613bd0576000816000905550600101613bb8565b5090565b5b80821115613bed576000816000905550600101613bd5565b5090565b6000613c04613bff84614f53565b614f2e565b905082815260208101848484011115613c2057613c1f61556c565b5b613c2b8482856152ac565b509392505050565b600081359050613c4281615599565b92915050565b600081519050613c5781615599565b92915050565b60008083601f840112613c7357613c72615553565b5b8235905067ffffffffffffffff811115613c9057613c8f61554e565b5b602083019150836020820283011115613cac57613cab615562565b5b9250929050565b60008083601f840112613cc957613cc8615553565b5b8235905067ffffffffffffffff811115613ce657613ce561554e565b5b602083019150836020820283011115613d0257613d01615562565b5b9250929050565b60008083601f840112613d1f57613d1e615553565b5b8235905067ffffffffffffffff811115613d3c57613d3b61554e565b5b602083019150836020820283011115613d5857613d57615562565b5b9250929050565b600081359050613d6e816155b0565b92915050565b600081519050613d83816155b0565b92915050565b600081359050613d98816155c7565b92915050565b600081359050613dad816155de565b92915050565b60008083601f840112613dc957613dc8615553565b5b8235905067ffffffffffffffff811115613de657613de561554e565b5b602083019150836001820283011115613e0257613e01615562565b5b9250929050565b600082601f830112613e1e57613e1d615553565b5b8135613e2e848260208601613bf1565b91505092915050565b60008083601f840112613e4d57613e4c615553565b5b8235905067ffffffffffffffff811115613e6a57613e6961554e565b5b602083019150836001820283011115613e8657613e85615562565b5b9250929050565b600081359050613e9c816155f5565b92915050565b600081359050613eb18161560c565b92915050565b600081359050613ec681615623565b92915050565b600060208284031215613ee257613ee1615576565b5b6000613ef084828501613c48565b91505092915050565b60008060208385031215613f1057613f0f615576565b5b600083013567ffffffffffffffff811115613f2e57613f2d615571565b5b613f3a85828601613d09565b92509250509250929050565b600060208284031215613f5c57613f5b615576565b5b6000613f6a84828501613d74565b91505092915050565b600060208284031215613f8957613f88615576565b5b6000613f9784828501613d89565b91505092915050565b60008060408385031215613fb757613fb6615576565b5b6000613fc585828601613d89565b9250506020613fd685828601613c33565b9150509250929050565b600080600060608486031215613ff957613ff8615576565b5b600061400786828701613d89565b935050602061401886828701613c33565b925050604061402986828701613c33565b9150509250925092565b60008060006060848603121561404c5761404b615576565b5b600061405a86828701613d89565b935050602061406b86828701613c33565b925050604061407c86828701613d5f565b9150509250925092565b60008060006040848603121561409f5761409e615576565b5b60006140ad86828701613d89565b935050602084013567ffffffffffffffff8111156140ce576140cd615571565b5b6140da86828701613c5d565b92509250509250925092565b60008060008060608587031215614100576140ff615576565b5b600061410e87828801613d89565b945050602085013567ffffffffffffffff81111561412f5761412e615571565b5b61413b87828801613cb3565b9350935050604061414e87828801613d5f565b91505092959194509250565b6000806040838503121561417157614170615576565b5b600061417f85828601613d89565b925050602061419085828601613d89565b9150509250929050565b6000806000606084860312156141b3576141b2615576565b5b60006141c186828701613d89565b93505060206141d286828701613d89565b92505060406141e386828701613d89565b9150509250925092565b60008060006060848603121561420657614205615576565b5b600061421486828701613d89565b935050602061422586828701613d89565b925050604061423686828701613e8d565b9150509250925092565b6000806040838503121561425757614256615576565b5b600061426585828601613d89565b925050602061427685828601613d9e565b9150509250929050565b60008060006060848603121561429957614298615576565b5b60006142a786828701613d89565b93505060206142b886828701613d9e565b92505060406142c986828701613c33565b9150509250925092565b6000806000604084860312156142ec576142eb615576565b5b60006142fa86828701613d89565b935050602084013567ffffffffffffffff81111561431b5761431a615571565b5b61432786828701613db3565b92509250509250925092565b60008060006040848603121561434c5761434b615576565b5b600061435a86828701613d89565b935050602084013567ffffffffffffffff81111561437b5761437a615571565b5b61438786828701613e37565b92509250509250925092565b6000806000806000606086880312156143af576143ae615576565b5b60006143bd88828901613d89565b955050602086013567ffffffffffffffff8111156143de576143dd615571565b5b6143ea88828901613e37565b9450945050604086013567ffffffffffffffff81111561440d5761440c615571565b5b61441988828901613e37565b92509250509295509295909350565b6000806040838503121561443f5761443e615576565b5b600061444d85828601613d89565b925050602061445e85828601613ea2565b9150509250929050565b6000806000806060858703121561448257614481615576565b5b600061449087828801613d89565b94505060206144a187828801613ea2565b935050604085013567ffffffffffffffff8111156144c2576144c1615571565b5b6144ce87828801613db3565b925092505092959194509250565b6000806000606084860312156144f5576144f4615576565b5b600061450386828701613d89565b935050602061451486828701613ea2565b925050604084013567ffffffffffffffff81111561453557614534615571565b5b61454186828701613e09565b9150509250925092565b6000806040838503121561456257614561615576565b5b600061457085828601613d89565b925050602061458185828601613eb7565b9150509250929050565b6000602082840312156145a1576145a0615576565b5b60006145af84828501613d9e565b91505092915050565b60006145c4838361461a565b60208301905092915050565b60006145dc8383614851565b60208301905092915050565b60006145f483836148d0565b905092915050565b61460581615276565b82525050565b614614816151dd565b82525050565b614623816151cb565b82525050565b614632816151cb565b82525050565b600061464382614fde565b61464d818561507d565b935061465883614f84565b8060005b8381101561468957815161467088826145b8565b975061467b8361502b565b92505060018101905061465c565b5085935050505092915050565b60006146a182614fe9565b6146ab818561506c565b93506146b683614f94565b8060005b838110156146ee576146cb82615528565b6146d588826145b8565b97506146e083615038565b9250506001810190506146ba565b5085935050505092915050565b600061470682614ff4565b614710818561509f565b935061471b83614fa9565b8060005b8381101561474c57815161473388826145d0565b975061473e83615045565b92505060018101905061471f565b5085935050505092915050565b600061476482614fff565b61476e818561508e565b935061477983614fb9565b8060005b838110156147b15761478e8261553b565b61479888826145d0565b97506147a383615052565b92505060018101905061477d565b5085935050505092915050565b60006147c98261500a565b6147d381856150b0565b9350836020820285016147e585614fce565b8060005b85811015614821578484038952815161480285826145e8565b945061480d8361505f565b925060208a019950506001810190506147e9565b50829750879550505050505092915050565b61483c816151ef565b82525050565b61484b816151ef565b82525050565b61485a816151fb565b82525050565b614869816151fb565b82525050565b61487881615205565b82525050565b600061488a83856150d2565b93506148978385846152ac565b6148a08361557b565b840190509392505050565b60006148b783856150e3565b93506148c48385846152ac565b82840190509392505050565b60006148db82615015565b6148e581856150c1565b93506148f58185602086016152bb565b6148fe8161557b565b840191505092915050565b600061491482615015565b61491e81856150d2565b935061492e8185602086016152bb565b6149378161557b565b840191505092915050565b600061494d82615015565b61495781856150e3565b93506149678185602086016152bb565b80840191505092915050565b600061497f83856150ee565b935061498c8385846152ac565b6149958361557b565b840190509392505050565b60006149ac83856150ff565b93506149b98385846152ac565b82840190509392505050565b60006149d082615020565b6149da81856150ee565b93506149ea8185602086016152bb565b6149f38161557b565b840191505092915050565b60006040830160008084018583036000870152614a1b8382614696565b92505060018401549050614a2e8161537e565b614a3b6020870182614851565b50819250505092915050565b60006040830160008084018583036000870152614a648382614759565b92505060018401549050614a7781615364565b614a846020870182614833565b50819250505092915050565b60006040830160008084018583036000870152614aad8382614696565b92505060018401549050614ac08161537e565b614acd6020870182614851565b50819250505092915050565b614ae281615231565b82525050565b614af18161525f565b82525050565b614b0081615269565b82525050565b6000614b138284866148ab565b91508190509392505050565b6000614b2b8284614942565b915081905092915050565b6000614b438284866149a0565b91508190509392505050565b6000602082019050614b646000830184614629565b92915050565b6000602082019050614b7f60008301846145fc565b92915050565b6000602082019050614b9a600083018461460b565b92915050565b6000604082019050614bb56000830185614629565b614bc26020830184614629565b9392505050565b60006040820190508181036000830152614be38185614638565b9050614bf26020830184614860565b9392505050565b60006040820190508181036000830152614c1381856146fb565b9050614c226020830184614842565b9392505050565b60006020820190508181036000830152614c4381846147be565b905092915050565b6000602082019050614c606000830184614842565b92915050565b6000602082019050614c7b6000830184614860565b92915050565b6000604082019050614c966000830185614860565b614ca36020830184614860565b9392505050565b6000602082019050614cbf600083018461486f565b92915050565b60006020820190508181036000830152614ce081848661487e565b90509392505050565b60006020820190508181036000830152614d038184614909565b905092915050565b60006040820190508181036000830152614d258186614909565b90508181036020830152614d3a81848661487e565b9050949350505050565b60006040820190508181036000830152614d5e8185614909565b9050614d6d6020830184614ad9565b9392505050565b60006060820190508181036000830152614d8e8186614909565b9050614d9d6020830185614ad9565b8181036040830152614daf8184614909565b9050949350505050565b60006020820190508181036000830152614dd4818486614973565b90509392505050565b60006020820190508181036000830152614df781846149c5565b905092915050565b60006020820190508181036000830152614e1981846149fe565b905092915050565b60006020820190508181036000830152614e3b8184614a47565b905092915050565b60006020820190508181036000830152614e5d8184614a90565b905092915050565b6000602082019050614e7a6000830184614ae8565b92915050565b6000604082019050614e956000830185614ae8565b8181036020830152614ea78184614909565b90509392505050565b6000602082019050614ec56000830184614af7565b92915050565b60008083356001602003843603038112614ee857614ee761555d565b5b80840192508235915067ffffffffffffffff821115614f0a57614f09615558565b5b602083019250600182023603831315614f2657614f25615567565b5b509250929050565b6000614f38614f49565b9050614f448282615398565b919050565b6000604051905090565b600067ffffffffffffffff821115614f6e57614f6d6154f9565b5b614f778261557b565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b6000819050602082019050919050565b600081519050919050565b600081549050919050565b600081519050919050565b600081549050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000600182019050919050565b6000602082019050919050565b6000600182019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006151158261525f565b91506151208361525f565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156151555761515461546c565b5b828201905092915050565b600061516b8261525f565b91506151768361525f565b9250828210156151895761518861546c565b5b828203905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600060ff82169050919050565b6000819050919050565b60006151d68261523f565b9050919050565b60006151e88261523f565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600061ffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061528182615288565b9050919050565b60006152938261529a565b9050919050565b60006152a58261523f565b9050919050565b82818337600083830152505050565b60005b838110156152d95780820151818401526020810190506152be565b838111156152e8576000848401525b50505050565b60006152f982615231565b9150600082141561530d5761530c61546c565b5b600182039050919050565b6000600282049050600182168061533057607f821691505b602082108114156153445761534361549b565b5b50919050565b600061535d6153588361558c565b615194565b9050919050565b60006153776153728361558c565b6151b4565b9050919050565b600061539161538c8361558c565b6151c1565b9050919050565b6153a18261557b565b810181811067ffffffffffffffff821117156153c0576153bf6154f9565b5b80604052505050565b60006153d482615231565b915061ffff8214156153e9576153e861546c565b5b600182019050919050565b60006153ff8261525f565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156154325761543161546c565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000615534825461534a565b9050919050565b6000615547825461537e565b9050919050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160001c9050919050565b6155a2816151cb565b81146155ad57600080fd5b50565b6155b9816151ef565b81146155c457600080fd5b50565b6155d0816151fb565b81146155db57600080fd5b50565b6155e781615205565b81146155f257600080fd5b50565b6155fe81615231565b811461560957600080fd5b50565b6156158161525f565b811461562057600080fd5b50565b61562c81615269565b811461563757600080fd5b5056fea26469706673582212205f46b36c67cd4d4ae0eb4cfc2c5dfd8898deff5fdb1ad1cd1152a9162dfbea5c64736f6c63430008060033