{
  "address": "0xc800DBc8ff9796E58EfBa2d7b35028DdD1997E5e",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_owner",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "coinType",
          "type": "uint256"
        },
        {
          "internalType": "contract IStandaloneReverseRegistrar",
          "name": "_defaultRegistrar",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_l2Registrar",
          "type": "address"
        },
        {
          "internalType": "contract IGatewayVerifier",
          "name": "verifier",
          "type": "address"
        },
        {
          "internalType": "string[]",
          "name": "gateways",
          "type": "string[]"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "dns",
          "type": "bytes"
        }
      ],
      "name": "DNSDecodingFailed",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "from",
          "type": "address"
        },
        {
          "internalType": "string[]",
          "name": "urls",
          "type": "string[]"
        },
        {
          "internalType": "bytes",
          "name": "request",
          "type": "bytes"
        },
        {
          "internalType": "bytes4",
          "name": "callback",
          "type": "bytes4"
        },
        {
          "internalType": "bytes",
          "name": "carry",
          "type": "bytes"
        }
      ],
      "name": "OffchainLookup",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        }
      ],
      "name": "OwnableInvalidOwner",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        }
      ],
      "name": "OwnableUnauthorizedAccount",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "RequestOverflow",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        }
      ],
      "name": "UnreachableName",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes4",
          "name": "selector",
          "type": "bytes4"
        }
      ],
      "name": "UnsupportedResolverProfile",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "string[]",
          "name": "urls",
          "type": "string[]"
        }
      ],
      "name": "GatewayURLsChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "verifier",
          "type": "address"
        }
      ],
      "name": "GatewayVerifierChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "previousOwner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "OwnershipTransferred",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "chainId",
      "outputs": [
        {
          "internalType": "uint32",
          "name": "",
          "type": "uint32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "coinType",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "defaultRegistrar",
      "outputs": [
        {
          "internalType": "contract IStandaloneReverseRegistrar",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "response",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "carry",
          "type": "bytes"
        }
      ],
      "name": "fetchCallback",
      "outputs": [],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "name": "gatewayURLs",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "gatewayVerifier",
      "outputs": [
        {
          "internalType": "contract IGatewayVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "l2Registrar",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "name",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "data",
          "type": "bytes"
        }
      ],
      "name": "resolve",
      "outputs": [
        {
          "internalType": "bytes",
          "name": "result",
          "type": "bytes"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes[]",
          "name": "values",
          "type": "bytes[]"
        },
        {
          "internalType": "uint8",
          "name": "",
          "type": "uint8"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "resolveNameCallback",
      "outputs": [
        {
          "internalType": "bytes",
          "name": "result",
          "type": "bytes"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address[]",
          "name": "addrs",
          "type": "address[]"
        },
        {
          "internalType": "uint8",
          "name": "perPage",
          "type": "uint8"
        }
      ],
      "name": "resolveNames",
      "outputs": [
        {
          "internalType": "string[]",
          "name": "names",
          "type": "string[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes[]",
          "name": "values",
          "type": "bytes[]"
        },
        {
          "internalType": "uint8",
          "name": "",
          "type": "uint8"
        },
        {
          "internalType": "bytes",
          "name": "extraData",
          "type": "bytes"
        }
      ],
      "name": "resolveNamesCallback",
      "outputs": [
        {
          "internalType": "string[]",
          "name": "names",
          "type": "string[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string[]",
          "name": "gateways",
          "type": "string[]"
        }
      ],
      "name": "setGatewayURLs",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "verifier",
          "type": "address"
        }
      ],
      "name": "setGatewayVerifier",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes4",
          "name": "interfaceId",
          "type": "bytes4"
        }
      ],
      "name": "supportsInterface",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0xbff59b105417167146ef7440af98e5c6f98fa3ed2c50c183cc360ed38b5de089",
  "receipt": {
    "to": null,
    "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F",
    "contractAddress": "0xc800DBc8ff9796E58EfBa2d7b35028DdD1997E5e",
    "transactionIndex": 22,
    "gasUsed": "3129170",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000001000000000002000000000000000001000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000080",
    "blockHash": "0xe00b2b73cdfaab2405e57b9fde07adb2788d8954503d123123b23af7c87c6379",
    "transactionHash": "0xbff59b105417167146ef7440af98e5c6f98fa3ed2c50c183cc360ed38b5de089",
    "logs": [
      {
        "transactionIndex": 22,
        "blockNumber": 22764838,
        "transactionHash": "0xbff59b105417167146ef7440af98e5c6f98fa3ed2c50c183cc360ed38b5de089",
        "address": "0xc800DBc8ff9796E58EfBa2d7b35028DdD1997E5e",
        "topics": [
          "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x000000000000000000000000fe89cc7abb2c4183683ab71653c4cdc9b02d44b7"
        ],
        "data": "0x",
        "logIndex": 121,
        "blockHash": "0xe00b2b73cdfaab2405e57b9fde07adb2788d8954503d123123b23af7c87c6379"
      }
    ],
    "blockNumber": 22764838,
    "cumulativeGasUsed": "6897307",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7",
    "2147492101",
    "0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9",
    "0x0000000000D8e504002cC26E3Ec46D81971C1664",
    "0x074c93cd956b0dd2cac0f9f11dda4d3893a88149",
    [
      "https://lb.drpc.org/gateway/unruggable?network=base",
      "https://base.3668.io"
    ]
  ],
  "numDeployments": 1,
  "solcInputHash": "66ae8ece08cf62450fe50df51b345695",
  "metadata": "{\"compiler\":{\"version\":\"0.8.26+commit.8a97fa7a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"coinType\",\"type\":\"uint256\"},{\"internalType\":\"contract IStandaloneReverseRegistrar\",\"name\":\"_defaultRegistrar\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Registrar\",\"type\":\"address\"},{\"internalType\":\"contract IGatewayVerifier\",\"name\":\"verifier\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"dns\",\"type\":\"bytes\"}],\"name\":\"DNSDecodingFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"request\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callback\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"carry\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RequestOverflow\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"UnreachableName\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"}],\"name\":\"UnsupportedResolverProfile\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"}],\"name\":\"GatewayURLsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"GatewayVerifierChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"chainId\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"coinType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultRegistrar\",\"outputs\":[{\"internalType\":\"contract IStandaloneReverseRegistrar\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"carry\",\"type\":\"bytes\"}],\"name\":\"fetchCallback\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gatewayVerifier\",\"outputs\":[{\"internalType\":\"contract IGatewayVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Registrar\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"result\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveNameCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"result\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"perPage\",\"type\":\"uint8\"}],\"name\":\"resolveNames\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveNamesCallback\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"setGatewayVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"DNSDecodingFailed(bytes)\":[{\"details\":\"The DNS-encoded name is malformed.\"}],\"OwnableInvalidOwner(address)\":[{\"details\":\"The owner is not a valid owner account. (eg. `address(0)`)\"}],\"OwnableUnauthorizedAccount(address)\":[{\"details\":\"The caller account is not authorized to perform an operation.\"}],\"UnreachableName(bytes)\":[{\"details\":\"Error selector: `0x5fe9a5df`\"}],\"UnsupportedResolverProfile(bytes4)\":[{\"details\":\"Error selector: `0x7b1c461b`\"}]},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"This function may execute over multiple steps.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The reverse name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"result\":\"The encoded response for the requested profile.\"}},\"resolveNameCallback(bytes[],uint8,bytes)\":{\"details\":\"CCIP-Read callback for `_resolveName()` (step 2 of 2).\",\"params\":{\"extraData\":\"The contextual data passed from `_resolveName()`.\",\"values\":\"The outputs for `GatewayRequest` (1 name).\"},\"returns\":{\"result\":\"The abi-encoded name for the given address.\"}},\"resolveNames(address[],uint8)\":{\"details\":\"This function may execute over multiple steps.\",\"params\":{\"addrs\":\"The addresses to resolve.\",\"perPage\":\"The maximum number of addresses to resolve per call.                Ignored if this function does not revert `OffchainLookup`.\"},\"returns\":{\"names\":\"The resolved names.\"}},\"resolveNamesCallback(bytes[],uint8,bytes)\":{\"details\":\"CCIP-Read callback for `_resolveNames()` (step 2 of 2).      Recursive if there are still addresses to resolve.\",\"params\":{\"extraData\":\"The contextual data passed from `_resolveNames()`.\",\"values\":\"The outputs for `GatewayRequest` (N names).\"},\"returns\":{\"names\":\"The resolved names.\"}},\"setGatewayURLs(string[])\":{\"params\":{\"gateways\":\"The new gateway URLs.\"}},\"setGatewayVerifier(address)\":{\"params\":{\"verifier\":\"The new verifier contract.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"Chain Reverse Resolver\",\"version\":1},\"userdoc\":{\"errors\":{\"UnreachableName(bytes)\":[{\"notice\":\"`name` is not a valid DNS-encoded ENSIP-19 reverse name or namespace.\"}],\"UnsupportedResolverProfile(bytes4)\":[{\"notice\":\"`resolve()` was called with a profile other than `name()` or `addr(*)`.\"}]},\"events\":{\"GatewayURLsChanged(string[])\":{\"notice\":\"Emitted when the gateway URLs are changed.\"},\"GatewayVerifierChanged(address)\":{\"notice\":\"Emitted when the gateway verifier is changed.\"}},\"kind\":\"user\",\"methods\":{\"chainId()\":{\"notice\":\"The EVM Chain ID corresponding to the `coinType`.\"},\"coinType()\":{\"notice\":\"The coin type for the resolver.\"},\"defaultRegistrar()\":{\"notice\":\"The reverse registrar contract for \\\"default.reverse\\\".\"},\"gatewayURLs(uint256)\":{\"notice\":\"Gateway URLs for the verifier contract.\"},\"gatewayVerifier()\":{\"notice\":\"The verifier contract for the L2 chain.\"},\"l2Registrar()\":{\"notice\":\"The reverse registrar address on the L2 chain.\"},\"resolve(bytes,bytes)\":{\"notice\":\"Resolves the following profiles according to ENSIP-10:         - `name()` if `name` is an ENSIP-19 reverse name of an EVM address for `coinType`.         - `addr(*) = registrar` if `name` is an ENSIP-19 reverse namespace for `coinType`.         Callers should enable EIP-3668.\"},\"resolveNames(address[],uint8)\":{\"notice\":\"Resolve multiple EVM addresses to names.         Callers should enable EIP-3668.\"},\"setGatewayURLs(string[])\":{\"notice\":\"Set gateway URLs.\"},\"setGatewayVerifier(address)\":{\"notice\":\"Set the verifier contract.\"}},\"notice\":\"Reverses an EVM address using the first non-null response from the following sources:         1. `L2ReverseRegistrar` on L2 chain via Unruggable Gateway         2. `IStandaloneReverseRegistrar` for \\\"default.reverse\\\"\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/reverseResolver/ChainReverseResolver.sol\":\"ChainReverseResolver\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-v5/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Context} from \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initial owner is set to the address provided by the deployer. This can\\n * later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n    address private _owner;\\n\\n    /**\\n     * @dev The caller account is not authorized to perform an operation.\\n     */\\n    error OwnableUnauthorizedAccount(address account);\\n\\n    /**\\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n     */\\n    error OwnableInvalidOwner(address owner);\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n     */\\n    constructor(address initialOwner) {\\n        if (initialOwner == address(0)) {\\n            revert OwnableInvalidOwner(address(0));\\n        }\\n        _transferOwnership(initialOwner);\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        _checkOwner();\\n        _;\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if the sender is not the owner.\\n     */\\n    function _checkOwner() internal view virtual {\\n        if (owner() != _msgSender()) {\\n            revert OwnableUnauthorizedAccount(_msgSender());\\n        }\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby disabling any functionality that is only available to the owner.\\n     */\\n    function renounceOwnership() public virtual onlyOwner {\\n        _transferOwnership(address(0));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual onlyOwner {\\n        if (newOwner == address(0)) {\\n            revert OwnableInvalidOwner(address(0));\\n        }\\n        _transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n}\\n\",\"keccak256\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-v5/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n\\n    function _contextSuffixLength() internal view virtual returns (uint256) {\\n        return 0;\\n    }\\n}\\n\",\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-v5/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n */\\nabstract contract ERC165 is IERC165 {\\n    /**\\n     * @dev See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n        return interfaceId == type(IERC165).interfaceId;\\n    }\\n}\\n\",\"keccak256\":\"0xddce8e17e3d3f9ed818b4f4c4478a8262aab8b11ed322f1bf5ed705bb4bd97fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts-v5/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n    /**\\n     * @dev Returns true if this contract implements the interface defined by\\n     * `interfaceId`. See the corresponding\\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\\n     * to learn more about how these ids are created.\\n     *\\n     * This function call must use less than 30 000 gas.\\n     */\\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x79796192ec90263f21b464d5bc90b777a525971d3de8232be80d9c4f9fb353b8\",\"license\":\"MIT\"},\"@unruggable/gateways/contracts/GatewayFetchTarget.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {GatewayRequest} from './GatewayRequest.sol';\\nimport {IGatewayVerifier} from './IGatewayVerifier.sol';\\nimport {IGatewayProtocol} from './IGatewayProtocol.sol';\\n\\nerror OffchainLookup(\\n    address from,\\n    string[] urls,\\n    bytes request,\\n    bytes4 callback,\\n    bytes carry\\n);\\n\\nabstract contract GatewayFetchTarget {\\n    struct Session {\\n        IGatewayVerifier verifier;\\n        bytes context;\\n        GatewayRequest req;\\n        bytes4 callback;\\n        bytes carry;\\n    }\\n\\n    function fetch(\\n        IGatewayVerifier verifier,\\n        GatewayRequest memory req,\\n        bytes4 callback\\n    ) internal view {\\n        fetch(verifier, req, callback, '', new string[](0));\\n    }\\n\\n    function fetch(\\n        IGatewayVerifier verifier,\\n        GatewayRequest memory req,\\n        bytes4 callback,\\n        bytes memory carry,\\n        string[] memory urls\\n    ) internal view {\\n        bytes memory context = verifier.getLatestContext();\\n        if (urls.length == 0) urls = verifier.gatewayURLs();\\n        revert OffchainLookup(\\n            address(this),\\n            urls,\\n            abi.encodeCall(IGatewayProtocol.proveRequest, (context, req)),\\n            this.fetchCallback.selector,\\n            abi.encode(Session(verifier, context, req, callback, carry))\\n        );\\n    }\\n\\n    function fetchCallback(\\n        bytes calldata response,\\n        bytes calldata carry\\n    ) external view {\\n        Session memory ses = abi.decode(carry, (Session));\\n        (bytes[] memory values, uint8 exitCode) = ses.verifier.getStorageValues(\\n            ses.context,\\n            ses.req,\\n            response\\n        );\\n        (bool ok, bytes memory ret) = address(this).staticcall(\\n            abi.encodeWithSelector(ses.callback, values, exitCode, ses.carry)\\n        );\\n        if (ok) {\\n            assembly {\\n                return(add(ret, 32), mload(ret))\\n            }\\n        } else {\\n            assembly {\\n                revert(add(ret, 32), mload(ret))\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x9f1ef19578f1568809dcd99521f528ba5f481cd447218f5183390606adf0a1d9\",\"license\":\"MIT\"},\"@unruggable/gateways/contracts/GatewayFetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {GatewayRequest, GatewayOP} from './GatewayRequest.sol';\\n\\n// only happens during request construction\\nerror RequestOverflow();\\n\\nlibrary GatewayFetcher {\\n    // verifier execution is only constrainted by stack and gas\\n    // max outputs = 255\\n    // NOTE: this is developer configurable\\n    uint256 constant MAX_OPS = 8192;\\n\\n    using GatewayFetcher for GatewayRequest;\\n\\n    function newRequest(\\n        uint8 outputs\\n    ) internal pure returns (GatewayRequest memory) {\\n        return newCommand().addByte(outputs);\\n    }\\n\\n    function newCommand() internal pure returns (GatewayRequest memory) {\\n        bytes memory v = new bytes(MAX_OPS);\\n        assembly {\\n            mstore(v, 0) // length = 0\\n        }\\n        return GatewayRequest(v);\\n    }\\n\\n    function encode(\\n        GatewayRequest memory r\\n    ) internal pure returns (bytes memory) {\\n        return abi.encodePacked(r.ops);\\n    }\\n\\n    function addByte(\\n        GatewayRequest memory r,\\n        uint8 i\\n    ) internal pure returns (GatewayRequest memory) {\\n        bytes memory v = r.ops;\\n        uint256 n = v.length;\\n        if (n >= MAX_OPS) revert RequestOverflow();\\n        assembly {\\n            mstore(v, add(n, 1)) // length += 1\\n            mstore8(add(add(v, 32), n), i) // append(i)\\n        }\\n        return r;\\n    }\\n    function addBytes(\\n        GatewayRequest memory r,\\n        bytes memory v\\n    ) internal pure returns (GatewayRequest memory) {\\n        bytes memory buf = r.ops;\\n        if (r.ops.length + v.length > MAX_OPS) revert RequestOverflow();\\n        assembly {\\n            let dst := add(add(buf, 32), mload(buf)) // ptr to write\\n            let src := add(v, 32) // ptr to start read\\n            for {\\n                let src_end := add(src, mload(v)) // ptr to stop read\\n            } lt(src, src_end) {\\n                src := add(src, 32)\\n                dst := add(dst, 32)\\n            } {\\n                mstore(dst, mload(src)) // copy word\\n            }\\n            mstore(buf, add(mload(buf), mload(v))) // length += v.length\\n        }\\n        return r;\\n    }\\n\\n    function debug(\\n        GatewayRequest memory r,\\n        string memory label\\n    ) internal pure returns (GatewayRequest memory) {\\n        bytes memory v = bytes(label);\\n        if (v.length >= 256) revert RequestOverflow();\\n        return r.addByte(GatewayOP.DEBUG).addByte(uint8(v.length)).addBytes(v);\\n    }\\n\\n    function push(\\n        GatewayRequest memory r,\\n        bool x\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(x ? 1 : 0);\\n    }\\n    function push(\\n        GatewayRequest memory r,\\n        bytes32 x\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(uint256(x));\\n    }\\n    function push(\\n        GatewayRequest memory r,\\n        address x\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(uint160(x));\\n    }\\n    function push(\\n        GatewayRequest memory r,\\n        uint256 x\\n    ) internal pure returns (GatewayRequest memory) {\\n        // NOTE: compact request building is not necessary\\n        // this could just be: return r.addByte(GatewayOP.PUSH_32).addBytes(abi.encode(x));\\n        if (x == 0) return r.addByte(GatewayOP.PUSH_0);\\n        uint8 n = clz(x); // number of leading zeros\\n        x <<= (n << 3); // right pad\\n        n = 32 - n; // width w/o pad\\n        r.addByte(GatewayOP.PUSH_0 + n);\\n        bytes memory v = r.ops;\\n        if (v.length + n > MAX_OPS) revert RequestOverflow();\\n        assembly {\\n            let len := mload(v)\\n            mstore(add(add(v, 32), len), x) // append(x)\\n            mstore(v, add(len, n)) // length += n\\n        }\\n        return r;\\n    }\\n    function clz(uint256 x) private pure returns (uint8 n) {\\n        if (x < (1 << 128)) {\\n            x <<= 128;\\n            n |= 16;\\n        }\\n        if (x < (1 << 192)) {\\n            x <<= 64;\\n            n |= 8;\\n        }\\n        if (x < (1 << 224)) {\\n            x <<= 32;\\n            n |= 4;\\n        }\\n        if (x < (1 << 240)) {\\n            x <<= 16;\\n            n |= 2;\\n        }\\n        if (x < (1 << 248)) {\\n            n |= 1;\\n        }\\n    }\\n\\n    function push(\\n        GatewayRequest memory r,\\n        string memory s\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(bytes(s));\\n    }\\n    function push(\\n        GatewayRequest memory r,\\n        GatewayRequest memory p\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(p.encode());\\n    }\\n    function push(\\n        GatewayRequest memory r,\\n        bytes memory v\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.PUSH_BYTES).push(v.length).addBytes(v);\\n    }\\n\\n    function getSlot(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.GET_SLOT);\\n    }\\n    function getTarget(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.GET_TARGET);\\n    }\\n    function stackCount(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.STACK_SIZE);\\n    }\\n    function isContract(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.IS_CONTRACT);\\n    }\\n\\n    function pushStack(\\n        GatewayRequest memory r,\\n        uint256 i\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(i).addByte(GatewayOP.PUSH_STACK);\\n        // r.stackCount().push(1).subtract().push(i).subtract().addByte(GatewayOP.DUP);\\n    }\\n    function pushOutput(\\n        GatewayRequest memory r,\\n        uint256 i\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(i).addByte(GatewayOP.PUSH_OUTPUT);\\n    }\\n\\n    function target(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.SET_TARGET);\\n    }\\n    function setTarget(\\n        GatewayRequest memory r,\\n        address a\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(a).target();\\n    }\\n\\n    function output(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.SET_OUTPUT);\\n    }\\n    function setOutput(\\n        GatewayRequest memory r,\\n        uint8 i\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(i).output();\\n    }\\n    function eval(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(true).evalIf();\\n    }\\n    function evalIf(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.EVAL);\\n    }\\n    function evalLoop(\\n        GatewayRequest memory r,\\n        uint8 flags\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.evalLoop(flags, 255);\\n    }\\n    function evalLoop(\\n        GatewayRequest memory r,\\n        uint8 flags,\\n        uint256 count\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(count).addByte(GatewayOP.EVAL_LOOP).addByte(flags);\\n    }\\n    function exit(\\n        GatewayRequest memory r,\\n        uint8 exitCode\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(false).assertNonzero(exitCode);\\n    }\\n    function assertNonzero(\\n        GatewayRequest memory r,\\n        uint8 exitCode\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.ASSERT).addByte(exitCode);\\n    }\\n    function requireContract(\\n        GatewayRequest memory r,\\n        uint8 exitCode\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.isContract().assertNonzero(exitCode);\\n    }\\n    function requireNonzero(\\n        GatewayRequest memory r,\\n        uint8 exitCode\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.dup().assertNonzero(exitCode);\\n    }\\n\\n    function setSlot(\\n        GatewayRequest memory r,\\n        uint256 x\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(x).slot();\\n    }\\n    function offset(\\n        GatewayRequest memory r,\\n        uint256 dx\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(dx).addSlot();\\n    }\\n    function addSlot(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.ADD_SLOT);\\n        // return r.getSlot().add().slot();\\n    }\\n    function slot(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.SET_SLOT);\\n    }\\n    function follow(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.FOLLOW);\\n        // return r.getSlot().concat().keccak().slot();\\n    }\\n    function followIndex(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.getSlot().keccak().slot().addSlot();\\n    }\\n\\n    function read(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.READ_SLOT);\\n    }\\n    function read(\\n        GatewayRequest memory r,\\n        uint256 n\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(n).addByte(GatewayOP.READ_SLOTS);\\n    }\\n    function readBytes(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.READ_BYTES);\\n    }\\n    function readHashedBytes(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.READ_HASHED_BYTES);\\n    }\\n    function readArray(\\n        GatewayRequest memory r,\\n        uint256 step\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(step).addByte(GatewayOP.READ_ARRAY);\\n    }\\n\\n    function pop(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.POP);\\n    }\\n    function dup(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.dup(0);\\n    }\\n    function dup(\\n        GatewayRequest memory r,\\n        uint256 back\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(back).addByte(GatewayOP.DUP);\\n    }\\n    function swap(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.swap(1);\\n    }\\n    function swap(\\n        GatewayRequest memory r,\\n        uint256 back\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(back).addByte(GatewayOP.SWAP);\\n    }\\n\\n    function concat(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.CONCAT);\\n    }\\n    function keccak(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.KECCAK);\\n    }\\n    function slice(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.SLICE);\\n    }\\n    function slice(\\n        GatewayRequest memory r,\\n        uint256 pos,\\n        uint256 len\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(pos).push(len).slice();\\n    }\\n    function length(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.LENGTH);\\n    }\\n\\n    function plus(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.PLUS);\\n    }\\n    function twosComplement(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.not().push(1).plus();\\n    }\\n    function subtract(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.twosComplement().plus();\\n    }\\n    function times(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.TIMES);\\n    }\\n    function divide(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.DIVIDE);\\n    }\\n    function mod(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.MOD);\\n    }\\n    function pow(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.POW);\\n    }\\n    function and(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.AND);\\n    }\\n    function or(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.OR);\\n    }\\n    function xor(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.XOR);\\n    }\\n    function isZero(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.IS_ZERO);\\n    }\\n    function not(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.NOT);\\n    }\\n    function shl(\\n        GatewayRequest memory r,\\n        uint8 shift\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(shift).addByte(GatewayOP.SHIFT_LEFT);\\n    }\\n    function shr(\\n        GatewayRequest memory r,\\n        uint8 shift\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.push(shift).addByte(GatewayOP.SHIFT_RIGHT);\\n    }\\n    function eq(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.EQ);\\n    }\\n    function lt(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.LT);\\n    }\\n    function gt(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.addByte(GatewayOP.GT);\\n    }\\n    function neq(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.eq().isZero();\\n    }\\n    function lte(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.gt().isZero();\\n    }\\n    function gte(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.lt().isZero();\\n    }\\n    function dup2(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.dup(1).dup(1);\\n    }\\n    function min(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.dup2().gt().addByte(GatewayOP.SWAP).pop();\\n    }\\n    function max(\\n        GatewayRequest memory r\\n    ) internal pure returns (GatewayRequest memory) {\\n        return r.dup2().lt().addByte(GatewayOP.SWAP).pop();\\n    }\\n}\\n\",\"keccak256\":\"0x498fe39b6a869bbf8834e97b917177bba39e4b20f71da0b6bff4b2324acf0237\",\"license\":\"MIT\"},\"@unruggable/gateways/contracts/GatewayRequest.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nstruct GatewayRequest {\\n    bytes ops;\\n}\\n\\nlibrary EvalFlag {\\n    uint8 constant STOP_ON_SUCCESS = 1 << 0;\\n    uint8 constant STOP_ON_FAILURE = 1 << 1;\\n    uint8 constant ACQUIRE_STATE = 1 << 2;\\n    uint8 constant KEEP_ARGS = 1 << 3;\\n}\\n\\nlibrary GatewayOP {\\n    uint8 constant PUSH_0 = 0;\\n    uint8 constant PUSH_1 = 1;\\n    uint8 constant PUSH_2 = 2;\\n    uint8 constant PUSH_3 = 3;\\n    uint8 constant PUSH_4 = 4;\\n    uint8 constant PUSH_5 = 5;\\n    uint8 constant PUSH_6 = 6;\\n    uint8 constant PUSH_7 = 7;\\n    uint8 constant PUSH_8 = 8;\\n    uint8 constant PUSH_9 = 9;\\n    uint8 constant PUSH_10 = 10;\\n    uint8 constant PUSH_11 = 11;\\n    uint8 constant PUSH_12 = 12;\\n    uint8 constant PUSH_13 = 13;\\n    uint8 constant PUSH_14 = 14;\\n    uint8 constant PUSH_15 = 15;\\n    uint8 constant PUSH_16 = 16;\\n    uint8 constant PUSH_17 = 17;\\n    uint8 constant PUSH_18 = 18;\\n    uint8 constant PUSH_19 = 19;\\n    uint8 constant PUSH_20 = 20;\\n    uint8 constant PUSH_21 = 21;\\n    uint8 constant PUSH_22 = 22;\\n    uint8 constant PUSH_23 = 23;\\n    uint8 constant PUSH_24 = 24;\\n    uint8 constant PUSH_25 = 25;\\n    uint8 constant PUSH_26 = 26;\\n    uint8 constant PUSH_27 = 27;\\n    uint8 constant PUSH_28 = 28;\\n    uint8 constant PUSH_29 = 29;\\n    uint8 constant PUSH_30 = 30;\\n    uint8 constant PUSH_31 = 31;\\n    uint8 constant PUSH_32 = 32;\\n\\n    uint8 constant GET_SLOT = 33;\\n    uint8 constant GET_TARGET = 34;\\n    uint8 constant STACK_SIZE = 35;\\n\\tuint8 constant IS_CONTRACT = 36;\\n\\n    uint8 constant PUSH_BYTES = 40;\\n    uint8 constant PUSH_STACK = 41;\\n    uint8 constant PUSH_OUTPUT = 42;\\n\\n    uint8 constant SET_TARGET = 50;\\n    uint8 constant SET_OUTPUT = 51;\\n    uint8 constant EVAL_LOOP = 52;\\n    uint8 constant EVAL = 53;\\n    uint8 constant ASSERT = 54;\\n\\n    uint8 constant READ_SLOT = 60;\\n    uint8 constant READ_BYTES = 61;\\n    uint8 constant READ_ARRAY = 62;\\n    uint8 constant READ_HASHED_BYTES = 63;\\n    uint8 constant READ_SLOTS = 64;\\n\\n    uint8 constant SET_SLOT = 70;\\n    uint8 constant ADD_SLOT = 71;\\n    uint8 constant FOLLOW = 72;\\n\\n    uint8 constant DUP = 80;\\n    uint8 constant POP = 81;\\n    uint8 constant SWAP = 82;\\n\\n    uint8 constant KECCAK = 90;\\n    uint8 constant CONCAT = 91;\\n    uint8 constant SLICE = 92;\\n    uint8 constant LENGTH = 93;\\n\\n    uint8 constant PLUS = 100;\\n    uint8 constant TIMES = 101;\\n    uint8 constant DIVIDE = 102;\\n    uint8 constant MOD = 103;\\n\\tuint8 constant POW = 104;\\n\\n    uint8 constant AND = 110;\\n    uint8 constant OR = 111;\\n    uint8 constant XOR = 112;\\n    uint8 constant SHIFT_LEFT = 113;\\n    uint8 constant SHIFT_RIGHT = 114;\\n    uint8 constant NOT = 115;\\n\\n    uint8 constant IS_ZERO = 120;\\n    uint8 constant EQ = 121;\\n    uint8 constant LT = 122;\\n    uint8 constant GT = 123;\\n\\n    uint8 constant DEBUG = 255;\\n}\\n\",\"keccak256\":\"0x3e6ce7cae72d6d77a9a4b5644495b8621116be44511186d47efbb27ce0fc73f9\",\"license\":\"MIT\"},\"@unruggable/gateways/contracts/IGatewayProtocol.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {GatewayRequest} from './GatewayRequest.sol';\\n\\ninterface IGatewayProtocol {\\n    function proveRequest(\\n        bytes memory context,\\n        GatewayRequest memory req\\n    ) external pure returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x44bfb072540c1b48081933e1f5874697e5476704f8a0f04e8cbdad6773bd9f86\",\"license\":\"MIT\"},\"@unruggable/gateways/contracts/IGatewayVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {GatewayRequest} from './GatewayRequest.sol';\\n\\nerror CommitTooOld(uint256 latest, uint256 got, uint256 window);\\nerror CommitTooNew(uint256 latest, uint256 got);\\n\\ninterface IGatewayVerifier {\\n    function getLatestContext() external view returns (bytes memory);\\n    function gatewayURLs() external view returns (string[] memory);\\n\\n    function getStorageValues(\\n        bytes memory context,\\n        GatewayRequest memory req,\\n        bytes memory proof\\n    ) external view returns (bytes[] memory values, uint8 exitCode);\\n}\\n\",\"keccak256\":\"0xd56c8ace6aba1354dd4c477b566343b641f57a8c4ef88e1d84294d3727552284\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/// Interface for the legacy (ETH-only) addr function.\\ninterface IAddrResolver {\\n    event AddrChanged(bytes32 indexed node, address a);\\n\\n    /// Returns the address associated with an ENS node.\\n    /// @param node The ENS node to query.\\n    /// @return The associated address.\\n    function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x91dd0c350698c505d6c7e4c919da9f981d4b8d7ad062e25073fa1f6af7cb79d1\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/// Interface for the new (multicoin) addr function.\\ninterface IAddressResolver {\\n    event AddressChanged(\\n        bytes32 indexed node,\\n        uint256 coinType,\\n        bytes newAddress\\n    );\\n\\n    function addr(\\n        bytes32 node,\\n        uint256 coinType\\n    ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x8da5dd0fc1c5ab4f47e03c23126976a86d4b2dbeac161e70e3af9e2a13330cf0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n    function resolve(\\n        bytes memory name,\\n        bytes memory data\\n    ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n    event NameChanged(bytes32 indexed node, string name);\\n\\n    /// Returns the name associated with an ENS node, for reverse records.\\n    /// Defined in EIP181.\\n    /// @param node The ENS node to query.\\n    /// @return The associated name.\\n    function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x3ab986332e0baad7aeb4b426aace3aa1c235be5efff8db4b6f1ce501bcdd9e68\",\"license\":\"MIT\"},\"contracts/reverseRegistrar/IStandaloneReverseRegistrar.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\n/// @notice Interface for a standalone reverse registrar.\\ninterface IStandaloneReverseRegistrar {\\n    /// @notice Emitted when the name for an address is changed.\\n    ///\\n    /// @param addr The address of the reverse record.\\n    /// @param name The name of the reverse record.\\n    event NameForAddrChanged(address indexed addr, string name);\\n\\n    /// @notice Returns the name for an address.\\n    ///\\n    /// @param addr The address to get the name for.\\n    /// @return The name for the address.\\n    function nameForAddr(address addr) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x693ab3a5dcd95a80a2a4a2418ce48092d20d11da1e39d17c87ab3f1641ceaf6e\",\"license\":\"MIT\"},\"contracts/reverseResolver/AbstractReverseResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts-v5/utils/introspection/ERC165.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {IAddressResolver} from \\\"../resolvers/profiles/IAddressResolver.sol\\\";\\nimport {IAddrResolver} from \\\"../resolvers/profiles/IAddrResolver.sol\\\";\\nimport {INameResolver} from \\\"../resolvers/profiles/INameResolver.sol\\\";\\nimport {INameReverser} from \\\"./INameReverser.sol\\\";\\nimport {ENSIP19, COIN_TYPE_DEFAULT, COIN_TYPE_ETH} from \\\"../utils/ENSIP19.sol\\\";\\n\\nabstract contract AbstractReverseResolver is\\n    IExtendedResolver,\\n    INameReverser,\\n    ERC165\\n{\\n    /// @notice The coin type for the resolver.\\n    uint256 public immutable coinType;\\n\\n    /// @notice The address returned by `addr(coinType)` for the resolver.\\n    address private immutable registrar;\\n\\n    /// @notice `resolve()` was called with a profile other than `name()` or `addr(*)`.\\n    /// @dev Error selector: `0x7b1c461b`\\n    error UnsupportedResolverProfile(bytes4 selector);\\n\\n    /// @notice `name` is not a valid DNS-encoded ENSIP-19 reverse name or namespace.\\n    /// @dev Error selector: `0x5fe9a5df`\\n    error UnreachableName(bytes name);\\n\\n    constructor(uint256 _coinType, address _registrar) {\\n        coinType = _coinType;\\n        registrar = _registrar;\\n    }\\n\\n    /// @inheritdoc ERC165\\n    function supportsInterface(\\n        bytes4 interfaceId\\n    ) public view override returns (bool) {\\n        return\\n            interfaceId == type(IExtendedResolver).interfaceId ||\\n            interfaceId == type(INameReverser).interfaceId ||\\n            super.supportsInterface(interfaceId);\\n    }\\n\\n    /// @notice The EVM Chain ID corresponding to the `coinType`.\\n    function chainId() external view returns (uint32) {\\n        return ENSIP19.chainFromCoinType(coinType);\\n    }\\n\\n    /// @dev Resolve one address to a name.\\n    ///      If this reverts `OffchainLookup`, it must return an abi-encoded result since\\n    ///      it is invoked during `resolve()`.\\n    function _resolveName(\\n        address addr\\n    ) internal view virtual returns (string memory name);\\n\\n    /// @notice Resolves the following profiles according to ENSIP-10:\\n    ///         - `name()` if `name` is an ENSIP-19 reverse name of an EVM address for `coinType`.\\n    ///         - `addr(*) = registrar` if `name` is an ENSIP-19 reverse namespace for `coinType`.\\n    ///         Callers should enable EIP-3668.\\n    /// @dev This function may execute over multiple steps.\\n    /// @param name The reverse name to resolve, in normalised and DNS-encoded form.\\n    /// @param data The resolution data, as specified in ENSIP-10.\\n    /// @return result The encoded response for the requested profile.\\n    function resolve(\\n        bytes calldata name,\\n        bytes calldata data\\n    ) external view returns (bytes memory result) {\\n        bytes4 selector = bytes4(data);\\n        if (selector == INameResolver.name.selector) {\\n            (bytes memory a, uint256 ct) = ENSIP19.parse(name);\\n            if (\\n                a.length != 20 ||\\n                !(\\n                    coinType == COIN_TYPE_DEFAULT\\n                        ? ENSIP19.isEVMCoinType(ct)\\n                        : ct == coinType\\n                )\\n            ) {\\n                revert UnreachableName(name);\\n            }\\n            address addr = address(bytes20(a));\\n            return abi.encode(_resolveName(addr));\\n        } else if (selector == IAddrResolver.addr.selector) {\\n            (bool valid, ) = ENSIP19.parseNamespace(name, 0);\\n            if (!valid) revert UnreachableName(name);\\n            return\\n                abi.encode(coinType == COIN_TYPE_ETH ? registrar : address(0));\\n        } else if (selector == IAddressResolver.addr.selector) {\\n            (bool valid, ) = ENSIP19.parseNamespace(name, 0);\\n            if (!valid) revert UnreachableName(name);\\n            (, uint256 ct) = abi.decode(data[4:], (bytes32, uint256));\\n            return\\n                abi.encode(\\n                    coinType == ct ? abi.encodePacked(registrar) : new bytes(0)\\n                );\\n        } else {\\n            revert UnsupportedResolverProfile(selector);\\n        }\\n    }\\n\\n    // `INameReverser.resolveNames()` is not implemented here because it causes\\n    // an incorrect \\\"Unreachable code\\\" compiler warning if `_resolveName()` reverts.\\n    // https://github.com/ethereum/solidity/issues/15426#issuecomment-2917868211\\n    //\\n    // /// @inheritdoc INameReverser\\n    // function resolveNames(\\n    //     address[] memory addrs,\\n    //     uint8 /*perPage*/\\n    // ) external view returns (string[] memory names) {\\n    //     names = new string[](addrs.length);\\n    //     for (uint256 i; i < addrs.length; i++) {\\n    //         names[i] = _resolveName(addrs[i]);\\n    //     }\\n    // }\\n}\\n\",\"keccak256\":\"0x8ca67570f493d6baa3dc08dfad7313b91ca3dffb86f70f46f6c295f1f1ff449c\",\"license\":\"MIT\"},\"contracts/reverseResolver/ChainReverseResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.17;\\n\\nimport {AbstractReverseResolver} from \\\"./AbstractReverseResolver.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts-v5/access/Ownable.sol\\\";\\nimport {GatewayFetchTarget, IGatewayVerifier} from \\\"@unruggable/gateways/contracts/GatewayFetchTarget.sol\\\";\\nimport {GatewayFetcher, GatewayRequest} from \\\"@unruggable/gateways/contracts/GatewayFetcher.sol\\\";\\nimport {IStandaloneReverseRegistrar} from \\\"../reverseRegistrar/IStandaloneReverseRegistrar.sol\\\";\\nimport {INameReverser} from \\\"./INameReverser.sol\\\";\\n\\n/// @title Chain Reverse Resolver\\n/// @notice Reverses an EVM address using the first non-null response from the following sources:\\n///         1. `L2ReverseRegistrar` on L2 chain via Unruggable Gateway\\n///         2. `IStandaloneReverseRegistrar` for \\\"default.reverse\\\"\\ncontract ChainReverseResolver is\\n    AbstractReverseResolver,\\n    GatewayFetchTarget,\\n    Ownable\\n{\\n    using GatewayFetcher for GatewayRequest;\\n\\n    /// @notice The reverse registrar contract for \\\"default.reverse\\\".\\n    IStandaloneReverseRegistrar public immutable defaultRegistrar;\\n\\n    /// @notice The reverse registrar address on the L2 chain.\\n    address public immutable l2Registrar;\\n\\n    /// @notice Storage slot for the names mapping in `L2ReverseRegistrar`.\\n    uint256 constant NAMES_SLOT = 0;\\n\\n    /// @notice The verifier contract for the L2 chain.\\n    IGatewayVerifier public gatewayVerifier;\\n\\n    /// @notice Gateway URLs for the verifier contract.\\n    string[] public gatewayURLs;\\n\\n    /// @notice Emitted when the gateway verifier is changed.\\n    event GatewayVerifierChanged(address verifier);\\n\\n    /// @notice Emitted when the gateway URLs are changed.\\n    event GatewayURLsChanged(string[] urls);\\n\\n    constructor(\\n        address _owner,\\n        uint256 coinType,\\n        IStandaloneReverseRegistrar _defaultRegistrar,\\n        address _l2Registrar,\\n        IGatewayVerifier verifier,\\n        string[] memory gateways\\n    ) Ownable(_owner) AbstractReverseResolver(coinType, _l2Registrar) {\\n        defaultRegistrar = _defaultRegistrar;\\n        l2Registrar = _l2Registrar;\\n        gatewayVerifier = verifier;\\n        gatewayURLs = gateways;\\n    }\\n\\n    /// @notice Set gateway URLs.\\n    /// @param gateways The new gateway URLs.\\n    function setGatewayURLs(string[] memory gateways) external onlyOwner {\\n        gatewayURLs = gateways;\\n        emit GatewayURLsChanged(gateways);\\n    }\\n\\n    /// @notice Set the verifier contract.\\n    /// @param verifier The new verifier contract.\\n    function setGatewayVerifier(address verifier) external onlyOwner {\\n        gatewayVerifier = IGatewayVerifier(verifier);\\n        emit GatewayVerifierChanged(verifier);\\n    }\\n\\n    /// @inheritdoc AbstractReverseResolver\\n    /// @dev This function executes over multiple steps (step 1 of 2).\\n    function _resolveName(\\n        address addr\\n    ) internal view override returns (string memory) {\\n        GatewayRequest memory req = GatewayFetcher.newRequest(1);\\n        req.setTarget(l2Registrar); // target L2 registrar\\n        req.setSlot(NAMES_SLOT).push(addr).follow().readBytes(); // names[addr]\\n        req.setOutput(0);\\n        fetch(\\n            gatewayVerifier,\\n            req,\\n            this.resolveNameCallback.selector,\\n            abi.encode(addr),\\n            gatewayURLs\\n        );\\n    }\\n\\n    /// @dev CCIP-Read callback for `_resolveName()` (step 2 of 2).\\n    /// @param values The outputs for `GatewayRequest` (1 name).\\n    /// @param extraData The contextual data passed from `_resolveName()`.\\n    /// @return result The abi-encoded name for the given address.\\n    function resolveNameCallback(\\n        bytes[] memory values,\\n        uint8 /* exitCode */,\\n        bytes calldata extraData\\n    ) external view returns (bytes memory result) {\\n        string memory name = string(values[0]);\\n        if (bytes(name).length == 0) {\\n            address addr = abi.decode(extraData, (address));\\n            name = defaultRegistrar.nameForAddr(addr);\\n        }\\n        result = abi.encode(name);\\n    }\\n\\n    /// @inheritdoc INameReverser\\n    function resolveNames(\\n        address[] memory addrs,\\n        uint8 perPage\\n    ) external view returns (string[] memory names) {\\n        names = new string[](addrs.length);\\n        _resolveNames(addrs, names, 0, perPage);\\n    }\\n\\n    /// @dev Resolve the next page of addresses to names.\\n    ///      This function executes over multiple steps (step 1 of 2).\\n    function _resolveNames(\\n        address[] memory addrs,\\n        string[] memory names,\\n        uint256 start,\\n        uint8 perPage\\n    ) internal view {\\n        uint256 end = start + perPage;\\n        if (end > addrs.length) end = addrs.length;\\n        uint8 count = uint8(end - start);\\n        if (count == 0) return; // done\\n        GatewayRequest memory req = GatewayFetcher.newRequest(count);\\n        req.setTarget(l2Registrar); // target L2 registrar\\n        for (uint256 i; i < count; i++) {\\n            req.setSlot(NAMES_SLOT).push(addrs[start + i]).follow().readBytes(); // names[addr[i]]\\n            req.setOutput(uint8(i));\\n        }\\n        fetch(\\n            gatewayVerifier,\\n            req,\\n            this.resolveNamesCallback.selector,\\n            abi.encode(addrs, names, start, perPage),\\n            gatewayURLs\\n        );\\n    }\\n\\n    /// @dev CCIP-Read callback for `_resolveNames()` (step 2 of 2).\\n    ///      Recursive if there are still addresses to resolve.\\n    /// @param values The outputs for `GatewayRequest` (N names).\\n    /// @param extraData The contextual data passed from `_resolveNames()`.\\n    /// @return names The resolved names.\\n    function resolveNamesCallback(\\n        bytes[] memory values,\\n        uint8 /* exitCode */,\\n        bytes calldata extraData\\n    ) external view returns (string[] memory names) {\\n        address[] memory addrs;\\n        uint256 start;\\n        uint8 perPage;\\n        (addrs, names, start, perPage) = abi.decode(\\n            extraData,\\n            (address[], string[], uint256, uint8)\\n        );\\n        for (uint256 i; i < values.length; i++) {\\n            string memory name = string(values[i]);\\n            if (bytes(name).length == 0) {\\n                name = defaultRegistrar.nameForAddr(addrs[i]);\\n            }\\n            names[start + i] = name;\\n        }\\n        _resolveNames(addrs, names, start + values.length, perPage);\\n    }\\n}\\n\",\"keccak256\":\"0x2fa4295ef29869b302951ece419910269c4fbc78acb8a6a6a23aa4b5a251b626\",\"license\":\"MIT\"},\"contracts/reverseResolver/INameReverser.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface INameReverser {\\n    /// @notice Resolve multiple EVM addresses to names.\\n    ///         Callers should enable EIP-3668.\\n    /// @dev This function may execute over multiple steps.\\n    /// @param addrs The addresses to resolve.\\n    /// @param perPage The maximum number of addresses to resolve per call.\\n    ///                Ignored if this function does not revert `OffchainLookup`.\\n    /// @return names The resolved names.\\n    function resolveNames(\\n        address[] memory addrs,\\n        uint8 perPage\\n    ) external view returns (string[] memory names);\\n}\\n\",\"keccak256\":\"0x7ffc12fd3d92799de64a63e936509e43bfb791e05900915a3a51235a2fe754d5\",\"license\":\"MIT\"},\"contracts/utils/ENSIP19.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {HexUtils} from \\\"../utils/HexUtils.sol\\\";\\nimport {NameCoder} from \\\"../utils/NameCoder.sol\\\";\\n\\nuint32 constant CHAIN_ID_ETH = 1;\\n\\nuint256 constant COIN_TYPE_ETH = 60;\\nuint256 constant COIN_TYPE_DEFAULT = 1 << 31; // 0x8000_0000\\n\\nstring constant SLUG_ETH = \\\"addr\\\"; // <=> COIN_TYPE_ETH\\nstring constant SLUG_DEFAULT = \\\"default\\\"; // <=> COIN_TYPE_DEFAULT\\nstring constant TLD_REVERSE = \\\"reverse\\\";\\n\\n/// @dev Library for generating reverse names according to ENSIP-19.\\n/// https://docs.ens.domains/ensip/19\\nlibrary ENSIP19 {\\n    /// @dev The supplied address was `0x`.\\n    error EmptyAddress();\\n\\n    /// @dev Extract Chain ID from `coinType`.\\n    /// @param coinType The coin type.\\n    /// @return The Chain ID or 0 if non-EVM Chain.\\n    function chainFromCoinType(\\n        uint256 coinType\\n    ) internal pure returns (uint32) {\\n        if (coinType == COIN_TYPE_ETH) return CHAIN_ID_ETH;\\n        coinType ^= COIN_TYPE_DEFAULT;\\n        return uint32(coinType < COIN_TYPE_DEFAULT ? coinType : 0);\\n    }\\n\\n    /// @dev Determine if Coin Type is for an EVM address.\\n    /// @param coinType The coin type.\\n    /// @return True if coin type represents an EVM address.\\n    function isEVMCoinType(uint256 coinType) internal pure returns (bool) {\\n        return coinType == COIN_TYPE_DEFAULT || chainFromCoinType(coinType) > 0;\\n    }\\n\\n    /// @dev Generate Reverse Name from Address + Coin Type.\\n    ///      Reverts `EmptyAddress` if `addressBytes` is `0x`.\\n    /// @param addressBytes The input address.\\n    /// @param coinType The coin type.\\n    /// @return The ENS reverse name, eg. `1234abcd.addr.reverse`.\\n    function reverseName(\\n        bytes memory addressBytes,\\n        uint256 coinType\\n    ) internal pure returns (string memory) {\\n        if (addressBytes.length == 0) {\\n            revert EmptyAddress();\\n        }\\n        return\\n            string(\\n                abi.encodePacked(\\n                    HexUtils.bytesToHex(addressBytes),\\n                    bytes1(\\\".\\\"),\\n                    coinType == COIN_TYPE_ETH\\n                        ? SLUG_ETH\\n                        : coinType == COIN_TYPE_DEFAULT\\n                            ? SLUG_DEFAULT\\n                            : HexUtils.unpaddedUintToHex(coinType, true),\\n                    bytes1(\\\".\\\"),\\n                    TLD_REVERSE\\n                )\\n            );\\n    }\\n\\n    /// @dev Parse Reverse Name into Address + Coin Type.\\n    ///      Matches: /^[0-9a-fA-F]+\\\\.([0-9a-f]{1,64}|addr|default)\\\\.reverse$/.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @return addressBytes The address or empty if invalid.\\n    /// @return coinType The coin type.\\n    function parse(\\n        bytes memory name\\n    ) internal pure returns (bytes memory addressBytes, uint256 coinType) {\\n        (, uint256 offset) = NameCoder.readLabel(name, 0);\\n        bool valid;\\n        (addressBytes, valid) = HexUtils.hexToBytes(name, 1, offset);\\n        if (!valid || addressBytes.length == 0) return (\\\"\\\", 0); // addressBytes not 1+ hex\\n        (valid, coinType) = parseNamespace(name, offset);\\n        if (!valid) return (\\\"\\\", 0); // invalid namespace\\n    }\\n\\n    /// @dev Parse Reverse Namespace into Coin Type.\\n    ///      Matches: /^([0-9a-f]{1,64}|addr|default)\\\\.reverse$/.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @param offset The offset to begin parsing.\\n    /// @return valid True if a valid reverse namespace.\\n    /// @return coinType The coin type.\\n    function parseNamespace(\\n        bytes memory name,\\n        uint256 offset\\n    ) internal pure returns (bool valid, uint256 coinType) {\\n        (bytes32 labelHash, uint256 offsetTLD) = NameCoder.readLabel(\\n            name,\\n            offset\\n        );\\n        if (labelHash == keccak256(bytes(SLUG_ETH))) {\\n            coinType = COIN_TYPE_ETH;\\n        } else if (labelHash == keccak256(bytes(SLUG_DEFAULT))) {\\n            coinType = COIN_TYPE_DEFAULT;\\n        } else if (labelHash == bytes32(0)) {\\n            return (false, 0); // no slug\\n        } else {\\n            (bytes32 word, bool validHex) = HexUtils.hexStringToBytes32(\\n                name,\\n                1 + offset,\\n                offsetTLD\\n            );\\n            if (!validHex) return (false, 0); // invalid coinType or too long\\n            coinType = uint256(word);\\n        }\\n        (labelHash, offset) = NameCoder.readLabel(name, offsetTLD);\\n        if (labelHash != keccak256(bytes(TLD_REVERSE))) return (false, 0); // invalid tld\\n        (labelHash, ) = NameCoder.readLabel(name, offset);\\n        if (labelHash != bytes32(0)) return (false, 0); // not tld\\n        valid = true;\\n    }\\n}\\n\",\"keccak256\":\"0x417e62b642c6a6c2efbb4601649b2fa1a9c46dc44c00869f687c074bfbe45945\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n    /// @dev Convert `hexString[pos:end]` to `bytes32`.\\n    ///      Accepts 0-64 hex-chars.\\n    ///      Uses right alignment: `1` &rarr; `0000000000000000000000000000000000000000000000000000000000000001`.\\n    /// @param hexString The string to parse.\\n    /// @param pos The index to start parsing.\\n    /// @param end The (exclusive) index to stop parsing.\\n    /// @return word The parsed bytes32.\\n    /// @return valid True if the parse was successful.\\n    function hexStringToBytes32(\\n        bytes memory hexString,\\n        uint256 pos,\\n        uint256 end\\n    ) internal pure returns (bytes32 word, bool valid) {\\n        uint256 nibbles = end - pos;\\n        if (nibbles > 64 || end > hexString.length) {\\n            return (bytes32(0), false); // too large or out of bounds\\n        }\\n        uint256 src;\\n        assembly {\\n            src := add(add(hexString, 32), pos)\\n        }\\n        valid = unsafeBytes(src, 0, nibbles);\\n        assembly {\\n            let pad := sub(32, shr(1, add(nibbles, 1))) // number of bytes\\n            word := shr(shl(3, pad), mload(0)) // right align\\n        }\\n    }\\n\\n    /// @dev Convert `hexString[pos:end]` to `address`.\\n    ///      Accepts exactly 40 hex-chars.\\n    /// @param hexString The string to parse.\\n    /// @param pos The index to start parsing.\\n    /// @param end The (exclusive) index to stop parsing.\\n    /// @return addr The parsed address.\\n    /// @return valid True if the parse was successful.\\n    function hexToAddress(\\n        bytes memory hexString,\\n        uint256 pos,\\n        uint256 end\\n    ) internal pure returns (address addr, bool valid) {\\n        if (end - pos != 40) return (address(0), false); // wrong length\\n        bytes32 word;\\n        (word, valid) = hexStringToBytes32(hexString, pos, end);\\n        addr = address(uint160(uint256(word)));\\n    }\\n\\n    /// @dev Convert `hexString[pos:end]` to `bytes`.\\n    ///      Accepts 0+ hex-chars.\\n    /// @param pos The index to start parsing.\\n    /// @param end The (exclusive) index to stop parsing.\\n    /// @return v The parsed bytes.\\n    /// @return valid True if the parse was successful.\\n    function hexToBytes(\\n        bytes memory hexString,\\n        uint256 pos,\\n        uint256 end\\n    ) internal pure returns (bytes memory v, bool valid) {\\n        uint256 nibbles = end - pos;\\n        v = new bytes((1 + nibbles) >> 1); // round up\\n        uint256 src;\\n        uint256 dst;\\n        assembly {\\n            src := add(add(hexString, 32), pos)\\n            dst := add(v, 32)\\n        }\\n        valid = unsafeBytes(src, dst, nibbles);\\n    }\\n\\n    /// @dev Convert arbitrary hex-encoded memory to bytes.\\n    ///      If nibbles is odd, leading hex-char is padded, eg. `F` &rarr; `0x0F`.\\n    ///      Matches: /^[0-9a-f]*$/i.\\n    /// @param src The memory offset of first hex-char of input.\\n    /// @param dst The memory offset of first byte of output (cannot alias `src`).\\n    /// @param nibbles The number of hex-chars to convert.\\n    /// @return valid True if all characters were hex.\\n    function unsafeBytes(\\n        uint256 src,\\n        uint256 dst,\\n        uint256 nibbles\\n    ) internal pure returns (bool valid) {\\n        assembly {\\n            function getHex(c, i) -> ascii {\\n                c := byte(i, c)\\n                // chars 48-57: 0-9\\n                if and(gt(c, 47), lt(c, 58)) {\\n                    ascii := sub(c, 48)\\n                    leave\\n                }\\n                // chars 65-70: A-F\\n                if and(gt(c, 64), lt(c, 71)) {\\n                    ascii := add(sub(c, 65), 10)\\n                    leave\\n                }\\n                // chars 97-102: a-f\\n                if and(gt(c, 96), lt(c, 103)) {\\n                    ascii := add(sub(c, 97), 10)\\n                    leave\\n                }\\n                // invalid char\\n                ascii := 0x100\\n            }\\n            valid := true\\n            let end := add(src, nibbles)\\n            if and(nibbles, 1) {\\n                let b := getHex(mload(src), 0) // \\\"f\\\" -> 15\\n                mstore8(dst, b) // write ascii byte\\n                src := add(src, 1) // update pointers\\n                dst := add(dst, 1)\\n                if gt(b, 255) {\\n                    valid := false\\n                    src := end // terminate loop\\n                }\\n            }\\n            for {} lt(src, end) {\\n                src := add(src, 2) // 2 nibbles\\n                dst := add(dst, 1) // per byte\\n            } {\\n                let word := mload(src) // read word (left aligned)\\n                let b := or(shl(4, getHex(word, 0)), getHex(word, 1)) // \\\"ff\\\" -> 255\\n                if gt(b, 255) {\\n                    valid := false\\n                    break\\n                }\\n                mstore8(dst, b) // write ascii byte\\n            }\\n        }\\n    }\\n\\n    /// @dev Format `address` as a hex string.\\n    /// @param addr The address to format.\\n    /// @return hexString The corresponding hex string w/o a 0x-prefix.\\n    function addressToHex(\\n        address addr\\n    ) internal pure returns (string memory hexString) {\\n        // return bytesToHex(abi.encodePacked(addr));\\n        hexString = new string(40);\\n        uint256 dst;\\n        assembly {\\n            mstore(0, addr)\\n            dst := add(hexString, 32)\\n        }\\n        unsafeHex(12, dst, 40);\\n    }\\n\\n    /// @dev Format `uint256` as a variable-length hex string without zero padding.\\n    /// * unpaddedUintToHex(0, true)  = \\\"0\\\"\\n    /// * unpaddedUintToHex(1, true)  = \\\"1\\\"\\n    /// * unpaddedUintToHex(0, false) = \\\"00\\\"\\n    /// * unpaddedUintToHex(1, false) = \\\"01\\\"\\n    /// @param value The number to format.\\n    /// @param dropZeroNibble If true, the leading byte will use one nibble if less than 16.\\n    /// @return hexString The corresponding hex string w/o an 0x-prefix.\\n    function unpaddedUintToHex(\\n        uint256 value,\\n        bool dropZeroNibble\\n    ) internal pure returns (string memory hexString) {\\n        uint256 temp = value;\\n        uint256 shift;\\n        for (uint256 b = 128; b >= 8; b >>= 1) {\\n            if (temp < (1 << b)) {\\n                shift += b; // number of zero upper bits\\n            } else {\\n                temp >>= b; // shift away lower half\\n            }\\n        }\\n        if (dropZeroNibble && temp < 16) shift += 4;\\n        uint256 nibbles = 64 - (shift >> 2);\\n        hexString = new string(nibbles);\\n        uint256 dst;\\n        assembly {\\n            mstore(0, shl(shift, value)) // left-align\\n            dst := add(hexString, 32)\\n        }\\n        unsafeHex(0, dst, nibbles);\\n    }\\n\\n    /// @dev Format `bytes` as a hex string.\\n    /// @param v The bytes to format.\\n    /// @return hexString The corresponding hex string w/o a 0x-prefix.\\n    function bytesToHex(\\n        bytes memory v\\n    ) internal pure returns (string memory hexString) {\\n        uint256 nibbles = v.length << 1;\\n        hexString = new string(nibbles);\\n        uint256 src;\\n        uint256 dst;\\n        assembly {\\n            src := add(v, 32)\\n            dst := add(hexString, 32)\\n        }\\n        unsafeHex(src, dst, nibbles);\\n    }\\n\\n    /// @dev Converts arbitrary memory to a hex string.\\n    /// @param src The memory offset of first nibble of input.\\n    /// @param dst The memory offset of first hex-char of output (can alias `src`).\\n    /// @param nibbles The number of nibbles to convert and the byte-length of the output.\\n    function unsafeHex(\\n        uint256 src,\\n        uint256 dst,\\n        uint256 nibbles\\n    ) internal pure {\\n        unchecked {\\n            for (uint256 end = dst + nibbles; dst < end; src += 32) {\\n                uint256 word;\\n                assembly {\\n                    word := mload(src)\\n                }\\n                for (uint256 shift = 256; dst < end && shift > 0; dst++) {\\n                    uint256 b = (word >> (shift -= 4)) & 15; // each nibble\\n                    b = b < 10 ? b + 0x30 : b + 0x57; // (\\\"a\\\" - 10) => 0x57\\n                    assembly {\\n                        mstore8(dst, b)\\n                    }\\n                }\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x48e51ac631fabaa3e659cdc9f3c5743fa76e999213d65e931c486f9375dd2d4f\",\"license\":\"MIT\"},\"contracts/utils/NameCoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {HexUtils} from \\\"../utils/HexUtils.sol\\\";\\n\\n/// @dev Library for encoding/decoding names.\\n///\\n/// An ENS name is stop-separated labels, eg. \\\"aaa.bb.c\\\".\\n///\\n/// A DNS-encoded name is composed of byte length-prefixed labels with a terminator byte.\\n/// eg. \\\"\\\\x03aaa\\\\x02bb\\\\x01c\\\\x00\\\".\\n/// - maximum label length is 255 bytes.\\n/// - length = 0 is reserved for the terminator (root).\\n///\\n/// To encode a label larger than 255 bytes, use a hashed label.\\n/// A label of any length can be converted to a hashed label.\\n///\\n/// A hashed label is encoded as \\\"[\\\" + toHex(keccak256(label)) + \\\"]\\\".\\n/// eg. [af2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc] = \\\"vitalik\\\".\\n/// - always 66 bytes.\\n/// - matches: `/^\\\\[[0-9a-f]{64}\\\\]$/`.\\n///\\n/// w/o hashed labels: `dns.length == 2 + ens.length` and the mapping is injective.\\n///  w/ hashed labels: `dns.length == 2 + ens.split('.').map(x => x.utf8Length).sum(n => n > 255 ? 66 : n)`.\\nlibrary NameCoder {\\n    /// @dev The DNS-encoded name is malformed.\\n    error DNSDecodingFailed(bytes dns);\\n\\n    /// @dev A label of the ENS name has an invalid size.\\n    error DNSEncodingFailed(string ens);\\n\\n    /// @dev Same as `BytesUtils.readLabel()` but supports hashed labels.\\n    ///      Only the last labelHash is zero.\\n    ///      Disallows hashed label of zero (eg. `[0..0]`) to prevent confusion with terminator.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @param idx The offset into `name` to start reading.\\n    /// @return labelHash The resulting labelhash.\\n    /// @return newIdx The offset into `name` of the next label.\\n    function readLabel(\\n        bytes memory name,\\n        uint256 idx\\n    ) internal pure returns (bytes32 labelHash, uint256 newIdx) {\\n        if (idx >= name.length) revert DNSDecodingFailed(name); // \\\"readLabel: expected length\\\"\\n        uint256 len = uint256(uint8(name[idx++]));\\n        newIdx = idx + len;\\n        if (newIdx > name.length) revert DNSDecodingFailed(name); // \\\"readLabel: expected label\\\"\\n        if (len == 66 && name[idx] == \\\"[\\\" && name[newIdx - 1] == \\\"]\\\") {\\n            bool valid;\\n            (labelHash, valid) = HexUtils.hexStringToBytes32(\\n                name,\\n                idx + 1,\\n                newIdx - 1\\n            ); // will not revert\\n            if (!valid || labelHash == bytes32(0)) {\\n                revert DNSDecodingFailed(name); // \\\"readLabel: malformed\\\" or null literal\\n            }\\n        } else if (len > 0) {\\n            assembly {\\n                labelHash := keccak256(add(add(name, idx), 32), len)\\n            }\\n        }\\n    }\\n\\n    /// @dev Same as `BytesUtils.namehash()` but supports hashed labels.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param name The DNS-encoded name.\\n    /// @param idx The offset into name start hashing.\\n    /// @return hash The resulting namehash.\\n    function namehash(\\n        bytes memory name,\\n        uint256 idx\\n    ) internal pure returns (bytes32 hash) {\\n        (hash, idx) = readLabel(name, idx);\\n        if (hash == bytes32(0)) {\\n            if (idx != name.length) revert DNSDecodingFailed(name); // \\\"namehash: Junk at end of name\\\"\\n        } else {\\n            bytes32 parent = namehash(name, idx);\\n            assembly {\\n                mstore(0, parent)\\n                mstore(32, hash)\\n                hash := keccak256(0, 64)\\n            }\\n        }\\n    }\\n\\n    /// @dev Convert DNS-encoded name to ENS name.\\n    ///      Reverts `DNSDecodingFailed`.\\n    /// @param dns The DNS-encoded name to convert, eg. `\\\\x03aaa\\\\x02bb\\\\x01c\\\\x00`.\\n    /// @return ens The equivalent ENS name, eg. `aaa.bb.c`.\\n    function decode(\\n        bytes memory dns\\n    ) internal pure returns (string memory ens) {\\n        unchecked {\\n            uint256 n = dns.length;\\n            if (n == 1 && dns[0] == 0) return \\\"\\\"; // only valid answer is root\\n            if (n < 3) revert DNSDecodingFailed(dns);\\n            bytes memory v = new bytes(n - 2); // always 2-shorter\\n            uint256 src;\\n            uint256 dst;\\n            while (src < n) {\\n                uint8 len = uint8(dns[src++]);\\n                if (len == 0) break;\\n                uint256 end = src + len;\\n                if (end > dns.length) revert DNSDecodingFailed(dns); // overflow\\n                if (dst > 0) v[dst++] = \\\".\\\"; // skip first stop\\n                while (src < end) {\\n                    bytes1 x = dns[src++]; // read byte\\n                    if (x == \\\".\\\") revert DNSDecodingFailed(dns); // malicious label\\n                    v[dst++] = x; // write byte\\n                }\\n            }\\n            if (src != dns.length) revert DNSDecodingFailed(dns); // junk at end\\n            return string(v);\\n        }\\n    }\\n\\n    /// @dev Convert ENS name to DNS-encoded name.\\n    ///      Hashes labels longer than 255 bytes.\\n    ///      Reverts `DNSEncodingFailed`.\\n    /// @param ens The ENS name to convert, eg. `aaa.bb.c`.\\n    /// @return dns The corresponding DNS-encoded name, eg. `\\\\x03aaa\\\\x02bb\\\\x01c\\\\x00`.\\n    function encode(\\n        string memory ens\\n    ) internal pure returns (bytes memory dns) {\\n        unchecked {\\n            uint256 n = bytes(ens).length;\\n            if (n == 0) return hex\\\"00\\\"; // root\\n            dns = new bytes(n + 2);\\n            uint256 start;\\n            assembly {\\n                start := add(dns, 32) // first byte of output\\n            }\\n            uint256 end = start; // remember position to write length\\n            for (uint256 i; i < n; i++) {\\n                bytes1 x = bytes(ens)[i]; // read byte\\n                if (x == \\\".\\\") {\\n                    start = _createHashedLabel(start, end);\\n                    if (start == 0) revert DNSEncodingFailed(ens);\\n                    end = start; // jump to next position\\n                } else {\\n                    assembly {\\n                        end := add(end, 1) // increase length\\n                        mstore(end, x) // write byte\\n                    }\\n                }\\n            }\\n            start = _createHashedLabel(start, end);\\n            if (start == 0) revert DNSEncodingFailed(ens);\\n            assembly {\\n                mstore8(start, 0) // terminal byte\\n                mstore(dns, sub(start, add(dns, 31))) // truncate length\\n            }\\n        }\\n    }\\n\\n    /// @dev Write the label length.\\n    ///      If longer than 255, writes a hashed label instead.\\n    /// @param start The memory offset of the length-prefixed label.\\n    /// @param end The memory offset at the end of the label.\\n    /// @return next The memory offset for the next label.\\n    ///              Returns 0 if label is empty (handled by caller).\\n    function _createHashedLabel(\\n        uint256 start,\\n        uint256 end\\n    ) internal pure returns (uint256 next) {\\n        uint256 size = end - start; // length of label\\n        if (size > 255) {\\n            assembly {\\n                mstore(0, keccak256(add(start, 1), size)) // compute hash of label\\n            }\\n            HexUtils.unsafeHex(0, start + 2, 64); // override label with hex(hash)\\n            assembly {\\n                mstore8(add(start, 1), 0x5B) // \\\"[\\\"\\n                mstore8(add(start, 66), 0x5D) // \\\"]\\\"\\n            }\\n            size = 66;\\n        }\\n        if (size > 0) {\\n            assembly {\\n                mstore8(start, size) // update length\\n            }\\n            next = start + 1 + size; // advance\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x8fd7af9cec38612e8041c13d4c3eb9c11fccdcbed4fac40020a4b84672f0aa85\",\"license\":\"MIT\"}},\"version\":1}",
  "bytecode": "0x61010060405234801561001157600080fd5b50604051613a49380380613a498339810160408190526100309161022f565b60808590526001600160a01b0380841660a0528690811661006b57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b610074816100bf565b506001600160a01b0384811660c05283811660e052600180546001600160a01b03191691841691909117905580516100b390600290602084019061010f565b50505050505050610518565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b828054828255906000526020600020908101928215610155579160200282015b828111156101555782518290610145908261045a565b509160200191906001019061012f565b50610161929150610165565b5090565b808211156101615760006101798282610182565b50600101610165565b50805461018e906103d1565b6000825580601f1061019e575050565b601f0160209004906000526020600020908101906101bc91906101bf565b50565b5b8082111561016157600081556001016101c0565b6001600160a01b03811681146101bc57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715610227576102276101e9565b604052919050565b60008060008060008060c0878903121561024857600080fd5b8651610253816101d4565b60208801516040890151919750955061026b816101d4565b606088015190945061027c816101d4565b608088015190935061028d816101d4565b60a08801519092506001600160401b038111156102a957600080fd5b8701601f810189136102ba57600080fd5b80516001600160401b038111156102d3576102d36101e9565b8060051b6102e3602082016101ff565b9182526020818401810192908101908c8411156102ff57600080fd5b6020850192505b838310156103bf5782516001600160401b0381111561032457600080fd5b8501603f81018e1361033557600080fd5b60208101516001600160401b03811115610351576103516101e9565b610364601f8201601f19166020016101ff565b8181528f6020808486010101111561037b57600080fd5b60005b8281101561039e578084016040015160208383018101919091520161037e565b50600060208383010152808552505050602082019150602083019250610306565b80955050505050509295509295509295565b600181811c908216806103e557607f821691505b60208210810361040557634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561045557806000526020600020601f840160051c810160208510156104325750805b601f840160051c820191505b81811015610452576000815560010161043e565b50505b505050565b81516001600160401b03811115610473576104736101e9565b6104878161048184546103d1565b8461040b565b6020601f8211600181146104bb57600083156104a35750848201515b600019600385901b1c1916600184901b178455610452565b600084815260208120601f198516915b828110156104eb57878501518255602094850194600190920191016104cb565b50848210156105095786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b60805160a05160c05160e0516134b2610597600039600081816102bf015281816110de0152611417015260008181610298015281816105600152610670015260008181610a9e0152610c40015260008181610162015281816108c7015281816108ed01528181610a7101528181610be20152610d0901526134b26000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c80638da5cb5b116100b2578063b16eab6511610081578063e31844fe11610066578063e31844fe146102e1578063e9481280146102f4578063f2fde38b1461030757600080fd5b8063b16eab6514610293578063d934ba62146102ba57600080fd5b80638da5cb5b146102325780638e5ea8df146102505780639061b923146102635780639a8a05921461027657600080fd5b806347ab2a21116100ee57806347ab2a21146101b25780635b4f069a146101d25780636407acc714610217578063715018a61461022a57600080fd5b806301ffc9a7146101205780631d7d85b2146101485780631fe93ea81461015d5780632edbbd1614610192575b600080fd5b61013361012e36600461231d565b61031a565b60405190151581526020015b60405180910390f35b61015b61015636600461235a565b6103ff565b005b6101847f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161013f565b6101a56101a03660046124d2565b610481565b60405161013f919061260c565b6101c56101c0366004612700565b6104e0565b60405161013f91906127f7565b6001546101f29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013f565b6101a5610225366004612700565b61061e565b61015b6107b6565b60005473ffffffffffffffffffffffffffffffffffffffff166101f2565b61015b61025e3660046128a1565b6107ca565b6101c56102713660046128d6565b610815565b61027e610d02565b60405163ffffffff909116815260200161013f565b6101f27f000000000000000000000000000000000000000000000000000000000000000081565b6101f27f000000000000000000000000000000000000000000000000000000000000000081565b61015b6102ef3660046128d6565b610d32565b6101c561030236600461292f565b610f2a565b61015b61031536600461235a565b610fd6565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f9061b9230000000000000000000000000000000000000000000000000000000014806103ad57507fffffffff0000000000000000000000000000000000000000000000000000000082167f2edbbd1600000000000000000000000000000000000000000000000000000000145b806103f957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b61040761103a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f6c4103197a18c1f386676f6e3684ccb255d1babd88559817b05c2682453deca0906020015b60405180910390a150565b6060825167ffffffffffffffff81111561049d5761049d612377565b6040519080825280602002602001820160405280156104d057816020015b60608152602001906001900390816104bb5790505b5090506103f9838260008561108d565b60606000856000815181106104f7576104f7612948565b6020026020010151905080516000036105f35760006105188486018661235a565b6040517f4ec3bd2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301529192507f000000000000000000000000000000000000000000000000000000000000000090911690634ec3bd2390602401600060405180830381865afa1580156105a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105ef91908101906129c7565b9150505b8060405160200161060491906127f7565b604051602081830303815290604052915050949350505050565b606080600080610630858701876129fc565b919650919450909250905060005b885181101561079257600089828151811061065b5761065b612948565b602002602001015190508051600003610762577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634ec3bd238684815181106106bc576106bc612948565b60200260200101516040518263ffffffff1660e01b81526004016106fc919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600060405180830381865afa158015610719573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261075f91908101906129c7565b90505b808661076e8487612ab0565b8151811061077e5761077e612948565b60209081029190910101525060010161063e565b506107ab83858a51856107a59190612ab0565b8461108d565b505050949350505050565b6107be61103a565b6107c860006112d8565b565b6107d261103a565b80516107e5906002906020840190612238565b507f91e1766c20958bc6fcd98acb2f87a586ae0d20a19f1e495c5dac2a5c5f6c9da281604051610476919061260c565b606060006108238385612ac3565b90507f96e0cbcf000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016109a5576000806108b088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061134d92505050565b915091508151601414158061091e575063800000007f000000000000000000000000000000000000000000000000000000000000000014610913577f0000000000000000000000000000000000000000000000000000000000000000811461091c565b61091c816113da565b155b156109625787876040517f5fe9a5df000000000000000000000000000000000000000000000000000000008152600401610959929190612b72565b60405180910390fd5b600061096d83612b86565b60601c905061097b81611401565b60405160200161098b91906127f7565b604051602081830303815290604052945050505050610cfa565b7fc4c4a822000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601610af8576000610a2f87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506115a9915050565b50905080610a6d5786866040517f5fe9a5df000000000000000000000000000000000000000000000000000000008152600401610959929190612b72565b603c7f000000000000000000000000000000000000000000000000000000000000000014610a9c576000610abe565b7f00000000000000000000000000000000000000000000000000000000000000005b6040805173ffffffffffffffffffffffffffffffffffffffff90921660208301520160405160208183030381529060405292505050610cfa565b7f0e3481fa000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601610ca4576000610b8287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506115a9915050565b50905080610bc05786866040517f5fe9a5df000000000000000000000000000000000000000000000000000000008152600401610959929190612b72565b6000610bcf8560048189612bf2565b810190610bdc9190612c1c565b915050807f000000000000000000000000000000000000000000000000000000000000000014610c1a57604080516000815260208101909152610c7b565b6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060601b1660208201526034016040516020818303038152906040525b604051602001610c8b91906127f7565b6040516020818303038152906040529350505050610cfa565b6040517f7b1c461b0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610959565b949350505050565b6000610d2d7f000000000000000000000000000000000000000000000000000000000000000061177a565b905090565b6000610d4082840184612cb1565b8051602082015160408084015190517fe3d1666e000000000000000000000000000000000000000000000000000000008152939450600093849373ffffffffffffffffffffffffffffffffffffffff169263e3d1666e92610da7928c908c90600401612db1565b600060405180830381865afa158015610dc4573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610e0a9190810190612e01565b915091506000803073ffffffffffffffffffffffffffffffffffffffff16856060015185858860800151604051602401610e4693929190612eca565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051610ecf9190612f6a565b600060405180830381855afa9150503d8060008114610f0a576040519150601f19603f3d011682016040523d82523d6000602084013e610f0f565b606091505b50915091508115610f2257805160208201f35b805160208201fd5b60028181548110610f3a57600080fd5b906000526020600020016000915090508054610f5590612f86565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8190612f86565b8015610fce5780601f10610fa357610100808354040283529160200191610fce565b820191906000526020600020905b815481529060010190602001808311610fb157829003601f168201915b505050505081565b610fde61103a565b73ffffffffffffffffffffffffffffffffffffffff811661102e576040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260006004820152602401610959565b611037816112d8565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107c8576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610959565b600061109c60ff831684612ab0565b905084518111156110ab575083515b60006110b78483612fd3565b90508060ff166000036110cb5750506112d2565b60006110d6826117a6565b9050611102817f00000000000000000000000000000000000000000000000000000000000000006117c7565b5060005b8260ff168110156111755761116161115c6111578a611125858b612ab0565b8151811061113557611135612948565b60200260200101516111516000876117ef90919063ffffffff16565b90611810565b61183f565b611859565b5061116c8282611873565b50600101611106565b506001546040516112ce9173ffffffffffffffffffffffffffffffffffffffff169083907f6407acc700000000000000000000000000000000000000000000000000000000906111cf908c908c908c908c90602001612fe6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181526002805460208181028601810190945280855291939290919060009084015b828210156112c557838290600052602060002001805461123890612f86565b80601f016020809104026020016040519081016040528092919081815260200182805461126490612f86565b80156112b15780601f10611286576101008083540402835291602001916112b1565b820191906000526020600020905b81548152906001019060200180831161129457829003601f168201915b505050505081526020019060010190611219565b50505050611897565b5050505b50505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008061135d846000611b43565b915050600061136e85600184611d58565b909450905080158061137f57508351155b156113a25760006040518060200160405280600081525090935093505050915091565b6113ac85836115a9565b93509050806113d35760006040518060200160405280600081525090935093505050915091565b5050915091565b600063800000008214806103f9575060006113f48361177a565b63ffffffff161192915050565b6060600061140f60016117a6565b905061143b817f00000000000000000000000000000000000000000000000000000000000000006117c7565b5061145161115c611157856111518560006117ef565b5061145d816000611873565b506001546040805173ffffffffffffffffffffffffffffffffffffffff86811660208301526115a393169184917f47ab2a21000000000000000000000000000000000000000000000000000000009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181526002805460208181028601810190945280855291939290919060009084015b828210156112c557838290600052602060002001805461151690612f86565b80601f016020809104026020016040519081016040528092919081815260200182805461154290612f86565b801561158f5780601f106115645761010080835404028352916020019161158f565b820191906000526020600020905b81548152906001019060200180831161157257829003601f168201915b5050505050815260200190600101906114f7565b50919050565b6000806000806115b98686611b43565b60408051808201909152600481527f616464720000000000000000000000000000000000000000000000000000000060209091015290925090507f1a1ebb7848707a05591e7f7176db930a822cb7ceab700d19f68c7f26724dafb6820161162357603c92506116d3565b60408051808201909152600781527f64656661756c74000000000000000000000000000000000000000000000000006020909101527f301183f75670b4a9a2edb381b1d7533ad1e4387f1c77824f5fd582d2a43998d8820161168b57638000000092506116d3565b8161169e57600080935093505050611773565b6000806116b6886116b0896001612ab0565b85611dde565b91509150806116cf576000809550955050505050611773565b5092505b6116dd8682611b43565b60408051808201909152600781527f7265766572736500000000000000000000000000000000000000000000000000602090910152955091507fdec08c9dbbdd0890e300eb5062089b2d4b1c40e3673bbccb5423f7b37dcf9a9c821461174b57600080935093505050611773565b6117558686611b43565b509150811561176c57600080935093505050611773565b6001935050505b9250929050565b6000603c820361178c57506001919050565b63800000009182189182106117a25760006103f9565b5090565b6040805160208101909152606081526103f9826117c1611e43565b90611e8b565b6040805160208101909152606081526117e86117e38484611810565b611ef0565b9392505050565b6040805160208101909152606081526117e861180b8484611f0a565b611fd3565b6040805160208101909152606081526117e88373ffffffffffffffffffffffffffffffffffffffff8416611f0a565b6040805160208101909152606081526103f9826048611e8b565b6040805160208101909152606081526103f982603d611e8b565b6040805160208101909152606081526117e86118928460ff8516611f0a565b611fed565b60008573ffffffffffffffffffffffffffffffffffffffff166387c484fe6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156118e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261192a91908101906129c7565b905081516000036119c9578573ffffffffffffffffffffffffffffffffffffffff1663b50f2fbc6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611980573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119c69190810190613066565b91505b308282876040516024016119de92919061311d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f31c1980f00000000000000000000000000000000000000000000000000000000179052815160a08101835273ffffffffffffffffffffffffffffffffffffffff8c1681528082018790528083018b90527fffffffff000000000000000000000000000000000000000000000000000000008a1660608201526080810189905291517fe31844fe0000000000000000000000000000000000000000000000000000000092611ae192909101613142565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f556f18300000000000000000000000000000000000000000000000000000000082526109599594939291600401613221565b60008083518310611b8257836040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161095991906127f7565b60008484611b8f816132aa565b955081518110611ba157611ba1612948565b016020015160f81c9050611bb58185612ab0565b91508451821115611bf457846040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161095991906127f7565b806042148015611c5c5750848481518110611c1157611c11612948565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f5b00000000000000000000000000000000000000000000000000000000000000145b8015611cca575084611c6f600184612fd3565b81518110611c7f57611c7f612948565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f5d00000000000000000000000000000000000000000000000000000000000000145b15611d3f576000611cf086611ce0876001612ab0565b611ceb600187612fd3565b611dde565b9094509050801580611d00575083155b15611d3957856040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161095991906127f7565b50611d50565b8015611d5057806020858701012092505b509250929050565b6060600080611d678585612fd3565b90506001611d758282612ab0565b901c67ffffffffffffffff811115611d8f57611d8f612377565b6040519080825280601f01601f191660200182016040528015611db9576020820181803683370190505b50925060208587018101908401611dd1828285612007565b9350505050935093915050565b60008080611dec8585612fd3565b90506040811180611dfd5750855184115b15611e0f575060009150819050611e3b565b858501602001611e2181600084612007565b92506001820160011c6020036000518160031b1c94505050505b935093915050565b60408051602081018252606081528151612000808252612020820190935290916000919060208201818036833750506000825250604080516020810190915290815292915050565b604080516020810190915260608152825180516120008110611ed9576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181018252838160208401015350929392505050565b6040805160208101909152606081526103f9826032611e8b565b60408051602081019091526060815281600003611f3357611f2c836000611e8b565b90506103f9565b6000611f3e83612153565b60f8600382901b169390931b929050611f588160206132e2565b9050611f6f611f688260006132fb565b8590611e8b565b508351805161200090611f869060ff851690612ab0565b1115611fbe576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516020818301019490945292019091525090565b6040805160208101909152606081526103f9826046611e8b565b6040805160208101909152606081526103f9826033611e8b565b60006120c1565b811a6000602f8211603a8310161561204957507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd081016103f9565b6047821060408311161561208057507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc981016103f9565b606782106060831116156120b757507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa981016103f9565b5061010092915050565b506001838201828216156120fd576120db6000865161200e565b80855360018601955060018501945060ff8111156120fb57600092508195505b505b8085101561214b57845161211260018261200e565b61211d60008361200e565b60041b17905060ff81111561213657600092505061214b565b808553506002850194506001840193506120fd565b509392505050565b60007001000000000000000000000000000000008210156121795760809190911b906010175b78010000000000000000000000000000000000000000000000008210156121a55760409190911b906008175b7c01000000000000000000000000000000000000000000000000000000008210156121d55760209190911b906004175b7e010000000000000000000000000000000000000000000000000000000000008210156122075760109190911b906002175b7f0100000000000000000000000000000000000000000000000000000000000000821015612233576001175b919050565b82805482825590600052602060002090810192821561227e579160200282015b8281111561227e578251829061226e9082613363565b5091602001919060010190612258565b506117a29291505b808211156117a257600061229a82826122a3565b50600101612286565b5080546122af90612f86565b6000825580601f106122bf575050565b601f01602090049060005260206000209081019061103791905b808211156117a257600081556001016122d9565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461223357600080fd5b60006020828403121561232f57600080fd5b6117e8826122ed565b73ffffffffffffffffffffffffffffffffffffffff8116811461103757600080fd5b60006020828403121561236c57600080fd5b81356117e881612338565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156123c9576123c9612377565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561241657612416612377565b604052919050565b600067ffffffffffffffff82111561243857612438612377565b5060051b60200190565b600082601f83011261245357600080fd5b81356124666124618261241e565b6123cf565b8082825260208201915060208360051b86010192508583111561248857600080fd5b602085015b838110156124ae5780356124a081612338565b83526020928301920161248d565b5095945050505050565b60ff8116811461103757600080fd5b8035612233816124b8565b600080604083850312156124e557600080fd5b823567ffffffffffffffff8111156124fc57600080fd5b61250885828601612442565b9250506020830135612519816124b8565b809150509250929050565b60005b8381101561253f578181015183820152602001612527565b50506000910152565b60008151808452612560816020860160208601612524565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208501945060208160051b8301016020850160005b83811015612600577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08584030188526125ea838351612548565b60209889019890935091909101906001016125b0565b50909695505050505050565b6020815260006117e86020830184612592565b600067ffffffffffffffff82111561263957612639612377565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006126736124618461261f565b905082815283838301111561268757600080fd5b828260208301376000602084830101529392505050565b600082601f8301126126af57600080fd5b6117e883833560208501612665565b60008083601f8401126126d057600080fd5b50813567ffffffffffffffff8111156126e857600080fd5b60208301915083602082850101111561177357600080fd5b6000806000806060858703121561271657600080fd5b843567ffffffffffffffff81111561272d57600080fd5b8501601f8101871361273e57600080fd5b803561274c6124618261241e565b8082825260208201915060208360051b85010192508983111561276e57600080fd5b602084015b838110156127b057803567ffffffffffffffff81111561279257600080fd5b6127a18c60208389010161269e565b84525060209283019201612773565b5096506127c392505050602086016124c7565b9250604085013567ffffffffffffffff8111156127df57600080fd5b6127eb878288016126be565b95989497509550505050565b6020815260006117e86020830184612548565b600082601f83011261281b57600080fd5b81356128296124618261241e565b8082825260208201915060208360051b86010192508583111561284b57600080fd5b602085015b838110156124ae57803567ffffffffffffffff81111561286f57600080fd5b8601603f8101881361288057600080fd5b61289288602083013560408401612665565b84525060209283019201612850565b6000602082840312156128b357600080fd5b813567ffffffffffffffff8111156128ca57600080fd5b610cfa8482850161280a565b600080600080604085870312156128ec57600080fd5b843567ffffffffffffffff81111561290357600080fd5b61290f878288016126be565b909550935050602085013567ffffffffffffffff8111156127df57600080fd5b60006020828403121561294157600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082601f83011261298857600080fd5b815160208301600061299c6124618461261f565b90508281528583830111156129b057600080fd5b6129be836020830184612524565b95945050505050565b6000602082840312156129d957600080fd5b815167ffffffffffffffff8111156129f057600080fd5b610cfa84828501612977565b60008060008060808587031215612a1257600080fd5b843567ffffffffffffffff811115612a2957600080fd5b612a3587828801612442565b945050602085013567ffffffffffffffff811115612a5257600080fd5b612a5e8782880161280a565b935050604085013591506060850135612a76816124b8565b939692955090935050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103f9576103f9612a81565b80357fffffffff000000000000000000000000000000000000000000000000000000008116906004841015612b22577fffffffff00000000000000000000000000000000000000000000000000000000808560040360031b1b82161691505b5092915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610cfa602083018486612b29565b805160208201517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000811691906014821015612beb577fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808360140360031b1b82161692505b5050919050565b60008085851115612c0257600080fd5b83861115612c0f57600080fd5b5050820193919092039150565b60008060408385031215612c2f57600080fd5b50508035926020909101359150565b803561223381612338565b600060208284031215612c5b57600080fd5b6040516020810167ffffffffffffffff81118282101715612c7e57612c7e612377565b604052905080823567ffffffffffffffff811115612c9b57600080fd5b612ca78582860161269e565b8252505092915050565b600060208284031215612cc357600080fd5b813567ffffffffffffffff811115612cda57600080fd5b820160a08185031215612cec57600080fd5b612cf46123a6565b612cfd82612c3e565b8152602082013567ffffffffffffffff811115612d1957600080fd5b612d258682850161269e565b602083015250604082013567ffffffffffffffff811115612d4557600080fd5b612d5186828501612c49565b604083015250612d63606083016122ed565b6060820152608082013567ffffffffffffffff811115612d8257600080fd5b612d8e8682850161269e565b608083015250949350505050565b6000815160208452610cfa6020850182612548565b606081526000612dc46060830187612548565b8281036020840152612dd68187612d9c565b90508281036040840152612deb818587612b29565b979650505050505050565b8051612233816124b8565b60008060408385031215612e1457600080fd5b825167ffffffffffffffff811115612e2b57600080fd5b8301601f81018513612e3c57600080fd5b8051612e4a6124618261241e565b8082825260208201915060208360051b850101925087831115612e6c57600080fd5b602084015b83811015612eae57805167ffffffffffffffff811115612e9057600080fd5b612e9f8a602083890101612977565b84525060209283019201612e71565b509450612ec19250505060208401612df6565b90509250929050565b6000606082016060835280865180835260808501915060808160051b86010192506020880160005b82811015612f41577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80878603018452612f2c858351612548565b94506020938401939190910190600101612ef2565b5050505060ff851660208401528281036040840152612f608185612548565b9695505050505050565b60008251612f7c818460208701612524565b9190910192915050565b600181811c90821680612f9a57607f821691505b6020821081036115a3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b818103818111156103f9576103f9612a81565b60808082528551908201819052600090602087019060a0840190835b8181101561303657835173ffffffffffffffffffffffffffffffffffffffff16835260209384019390920191600101613002565b5050838103602085015261304a8188612592565b9250505083604083015260ff8316606083015295945050505050565b60006020828403121561307857600080fd5b815167ffffffffffffffff81111561308f57600080fd5b8201601f810184136130a057600080fd5b80516130ae6124618261241e565b8082825260208201915060208360051b8501019250868311156130d057600080fd5b602084015b8381101561311257805167ffffffffffffffff8111156130f457600080fd5b61310389602083890101612977565b845250602092830192016130d5565b509695505050505050565b6040815260006131306040830185612548565b82810360208401526129be8185612d9c565b6020815273ffffffffffffffffffffffffffffffffffffffff82511660208201526000602083015160a0604084015261317e60c0840182612548565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160608501526131b98282612d9c565b9150507fffffffff00000000000000000000000000000000000000000000000000000000606085015116608084015260808401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160a08501526129be8282612548565b73ffffffffffffffffffffffffffffffffffffffff8616815260a06020820152600061325060a0830187612592565b82810360408401526132628187612548565b90507fffffffff0000000000000000000000000000000000000000000000000000000085166060840152828103608084015261329e8185612548565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036132db576132db612a81565b5060010190565b60ff82811682821603908111156103f9576103f9612a81565b60ff81811683821601908111156103f9576103f9612a81565b601f82111561335e57806000526020600020601f840160051c8101602085101561333b5750805b601f840160051c820191505b8181101561335b5760008155600101613347565b50505b505050565b815167ffffffffffffffff81111561337d5761337d612377565b6133918161338b8454612f86565b84613314565b6020601f8211600181146133e357600083156133ad5750848201515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b17845561335b565b6000848152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08516915b828110156134315787850151825560209485019460019092019101613411565b508482101561346d57868401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b60f8161c191681555b50505050600190811b0190555056fea26469706673582212207df73955a4cd1875e4422b5318e0811990c250304fd8716475d4a094f79a568a64736f6c634300081a0033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061011b5760003560e01c80638da5cb5b116100b2578063b16eab6511610081578063e31844fe11610066578063e31844fe146102e1578063e9481280146102f4578063f2fde38b1461030757600080fd5b8063b16eab6514610293578063d934ba62146102ba57600080fd5b80638da5cb5b146102325780638e5ea8df146102505780639061b923146102635780639a8a05921461027657600080fd5b806347ab2a21116100ee57806347ab2a21146101b25780635b4f069a146101d25780636407acc714610217578063715018a61461022a57600080fd5b806301ffc9a7146101205780631d7d85b2146101485780631fe93ea81461015d5780632edbbd1614610192575b600080fd5b61013361012e36600461231d565b61031a565b60405190151581526020015b60405180910390f35b61015b61015636600461235a565b6103ff565b005b6101847f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161013f565b6101a56101a03660046124d2565b610481565b60405161013f919061260c565b6101c56101c0366004612700565b6104e0565b60405161013f91906127f7565b6001546101f29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013f565b6101a5610225366004612700565b61061e565b61015b6107b6565b60005473ffffffffffffffffffffffffffffffffffffffff166101f2565b61015b61025e3660046128a1565b6107ca565b6101c56102713660046128d6565b610815565b61027e610d02565b60405163ffffffff909116815260200161013f565b6101f27f000000000000000000000000000000000000000000000000000000000000000081565b6101f27f000000000000000000000000000000000000000000000000000000000000000081565b61015b6102ef3660046128d6565b610d32565b6101c561030236600461292f565b610f2a565b61015b61031536600461235a565b610fd6565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f9061b9230000000000000000000000000000000000000000000000000000000014806103ad57507fffffffff0000000000000000000000000000000000000000000000000000000082167f2edbbd1600000000000000000000000000000000000000000000000000000000145b806103f957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b61040761103a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f6c4103197a18c1f386676f6e3684ccb255d1babd88559817b05c2682453deca0906020015b60405180910390a150565b6060825167ffffffffffffffff81111561049d5761049d612377565b6040519080825280602002602001820160405280156104d057816020015b60608152602001906001900390816104bb5790505b5090506103f9838260008561108d565b60606000856000815181106104f7576104f7612948565b6020026020010151905080516000036105f35760006105188486018661235a565b6040517f4ec3bd2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301529192507f000000000000000000000000000000000000000000000000000000000000000090911690634ec3bd2390602401600060405180830381865afa1580156105a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105ef91908101906129c7565b9150505b8060405160200161060491906127f7565b604051602081830303815290604052915050949350505050565b606080600080610630858701876129fc565b919650919450909250905060005b885181101561079257600089828151811061065b5761065b612948565b602002602001015190508051600003610762577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634ec3bd238684815181106106bc576106bc612948565b60200260200101516040518263ffffffff1660e01b81526004016106fc919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600060405180830381865afa158015610719573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261075f91908101906129c7565b90505b808661076e8487612ab0565b8151811061077e5761077e612948565b60209081029190910101525060010161063e565b506107ab83858a51856107a59190612ab0565b8461108d565b505050949350505050565b6107be61103a565b6107c860006112d8565b565b6107d261103a565b80516107e5906002906020840190612238565b507f91e1766c20958bc6fcd98acb2f87a586ae0d20a19f1e495c5dac2a5c5f6c9da281604051610476919061260c565b606060006108238385612ac3565b90507f96e0cbcf000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216016109a5576000806108b088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061134d92505050565b915091508151601414158061091e575063800000007f000000000000000000000000000000000000000000000000000000000000000014610913577f0000000000000000000000000000000000000000000000000000000000000000811461091c565b61091c816113da565b155b156109625787876040517f5fe9a5df000000000000000000000000000000000000000000000000000000008152600401610959929190612b72565b60405180910390fd5b600061096d83612b86565b60601c905061097b81611401565b60405160200161098b91906127f7565b604051602081830303815290604052945050505050610cfa565b7fc4c4a822000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601610af8576000610a2f87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506115a9915050565b50905080610a6d5786866040517f5fe9a5df000000000000000000000000000000000000000000000000000000008152600401610959929190612b72565b603c7f000000000000000000000000000000000000000000000000000000000000000014610a9c576000610abe565b7f00000000000000000000000000000000000000000000000000000000000000005b6040805173ffffffffffffffffffffffffffffffffffffffff90921660208301520160405160208183030381529060405292505050610cfa565b7f0e3481fa000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601610ca4576000610b8287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506115a9915050565b50905080610bc05786866040517f5fe9a5df000000000000000000000000000000000000000000000000000000008152600401610959929190612b72565b6000610bcf8560048189612bf2565b810190610bdc9190612c1c565b915050807f000000000000000000000000000000000000000000000000000000000000000014610c1a57604080516000815260208101909152610c7b565b6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060601b1660208201526034016040516020818303038152906040525b604051602001610c8b91906127f7565b6040516020818303038152906040529350505050610cfa565b6040517f7b1c461b0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610959565b949350505050565b6000610d2d7f000000000000000000000000000000000000000000000000000000000000000061177a565b905090565b6000610d4082840184612cb1565b8051602082015160408084015190517fe3d1666e000000000000000000000000000000000000000000000000000000008152939450600093849373ffffffffffffffffffffffffffffffffffffffff169263e3d1666e92610da7928c908c90600401612db1565b600060405180830381865afa158015610dc4573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610e0a9190810190612e01565b915091506000803073ffffffffffffffffffffffffffffffffffffffff16856060015185858860800151604051602401610e4693929190612eca565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051610ecf9190612f6a565b600060405180830381855afa9150503d8060008114610f0a576040519150601f19603f3d011682016040523d82523d6000602084013e610f0f565b606091505b50915091508115610f2257805160208201f35b805160208201fd5b60028181548110610f3a57600080fd5b906000526020600020016000915090508054610f5590612f86565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8190612f86565b8015610fce5780601f10610fa357610100808354040283529160200191610fce565b820191906000526020600020905b815481529060010190602001808311610fb157829003601f168201915b505050505081565b610fde61103a565b73ffffffffffffffffffffffffffffffffffffffff811661102e576040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260006004820152602401610959565b611037816112d8565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107c8576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610959565b600061109c60ff831684612ab0565b905084518111156110ab575083515b60006110b78483612fd3565b90508060ff166000036110cb5750506112d2565b60006110d6826117a6565b9050611102817f00000000000000000000000000000000000000000000000000000000000000006117c7565b5060005b8260ff168110156111755761116161115c6111578a611125858b612ab0565b8151811061113557611135612948565b60200260200101516111516000876117ef90919063ffffffff16565b90611810565b61183f565b611859565b5061116c8282611873565b50600101611106565b506001546040516112ce9173ffffffffffffffffffffffffffffffffffffffff169083907f6407acc700000000000000000000000000000000000000000000000000000000906111cf908c908c908c908c90602001612fe6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181526002805460208181028601810190945280855291939290919060009084015b828210156112c557838290600052602060002001805461123890612f86565b80601f016020809104026020016040519081016040528092919081815260200182805461126490612f86565b80156112b15780601f10611286576101008083540402835291602001916112b1565b820191906000526020600020905b81548152906001019060200180831161129457829003601f168201915b505050505081526020019060010190611219565b50505050611897565b5050505b50505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008061135d846000611b43565b915050600061136e85600184611d58565b909450905080158061137f57508351155b156113a25760006040518060200160405280600081525090935093505050915091565b6113ac85836115a9565b93509050806113d35760006040518060200160405280600081525090935093505050915091565b5050915091565b600063800000008214806103f9575060006113f48361177a565b63ffffffff161192915050565b6060600061140f60016117a6565b905061143b817f00000000000000000000000000000000000000000000000000000000000000006117c7565b5061145161115c611157856111518560006117ef565b5061145d816000611873565b506001546040805173ffffffffffffffffffffffffffffffffffffffff86811660208301526115a393169184917f47ab2a21000000000000000000000000000000000000000000000000000000009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181526002805460208181028601810190945280855291939290919060009084015b828210156112c557838290600052602060002001805461151690612f86565b80601f016020809104026020016040519081016040528092919081815260200182805461154290612f86565b801561158f5780601f106115645761010080835404028352916020019161158f565b820191906000526020600020905b81548152906001019060200180831161157257829003601f168201915b5050505050815260200190600101906114f7565b50919050565b6000806000806115b98686611b43565b60408051808201909152600481527f616464720000000000000000000000000000000000000000000000000000000060209091015290925090507f1a1ebb7848707a05591e7f7176db930a822cb7ceab700d19f68c7f26724dafb6820161162357603c92506116d3565b60408051808201909152600781527f64656661756c74000000000000000000000000000000000000000000000000006020909101527f301183f75670b4a9a2edb381b1d7533ad1e4387f1c77824f5fd582d2a43998d8820161168b57638000000092506116d3565b8161169e57600080935093505050611773565b6000806116b6886116b0896001612ab0565b85611dde565b91509150806116cf576000809550955050505050611773565b5092505b6116dd8682611b43565b60408051808201909152600781527f7265766572736500000000000000000000000000000000000000000000000000602090910152955091507fdec08c9dbbdd0890e300eb5062089b2d4b1c40e3673bbccb5423f7b37dcf9a9c821461174b57600080935093505050611773565b6117558686611b43565b509150811561176c57600080935093505050611773565b6001935050505b9250929050565b6000603c820361178c57506001919050565b63800000009182189182106117a25760006103f9565b5090565b6040805160208101909152606081526103f9826117c1611e43565b90611e8b565b6040805160208101909152606081526117e86117e38484611810565b611ef0565b9392505050565b6040805160208101909152606081526117e861180b8484611f0a565b611fd3565b6040805160208101909152606081526117e88373ffffffffffffffffffffffffffffffffffffffff8416611f0a565b6040805160208101909152606081526103f9826048611e8b565b6040805160208101909152606081526103f982603d611e8b565b6040805160208101909152606081526117e86118928460ff8516611f0a565b611fed565b60008573ffffffffffffffffffffffffffffffffffffffff166387c484fe6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156118e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261192a91908101906129c7565b905081516000036119c9578573ffffffffffffffffffffffffffffffffffffffff1663b50f2fbc6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611980573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119c69190810190613066565b91505b308282876040516024016119de92919061311d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f31c1980f00000000000000000000000000000000000000000000000000000000179052815160a08101835273ffffffffffffffffffffffffffffffffffffffff8c1681528082018790528083018b90527fffffffff000000000000000000000000000000000000000000000000000000008a1660608201526080810189905291517fe31844fe0000000000000000000000000000000000000000000000000000000092611ae192909101613142565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f556f18300000000000000000000000000000000000000000000000000000000082526109599594939291600401613221565b60008083518310611b8257836040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161095991906127f7565b60008484611b8f816132aa565b955081518110611ba157611ba1612948565b016020015160f81c9050611bb58185612ab0565b91508451821115611bf457846040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161095991906127f7565b806042148015611c5c5750848481518110611c1157611c11612948565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f5b00000000000000000000000000000000000000000000000000000000000000145b8015611cca575084611c6f600184612fd3565b81518110611c7f57611c7f612948565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f5d00000000000000000000000000000000000000000000000000000000000000145b15611d3f576000611cf086611ce0876001612ab0565b611ceb600187612fd3565b611dde565b9094509050801580611d00575083155b15611d3957856040517fba4adc2300000000000000000000000000000000000000000000000000000000815260040161095991906127f7565b50611d50565b8015611d5057806020858701012092505b509250929050565b6060600080611d678585612fd3565b90506001611d758282612ab0565b901c67ffffffffffffffff811115611d8f57611d8f612377565b6040519080825280601f01601f191660200182016040528015611db9576020820181803683370190505b50925060208587018101908401611dd1828285612007565b9350505050935093915050565b60008080611dec8585612fd3565b90506040811180611dfd5750855184115b15611e0f575060009150819050611e3b565b858501602001611e2181600084612007565b92506001820160011c6020036000518160031b1c94505050505b935093915050565b60408051602081018252606081528151612000808252612020820190935290916000919060208201818036833750506000825250604080516020810190915290815292915050565b604080516020810190915260608152825180516120008110611ed9576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181018252838160208401015350929392505050565b6040805160208101909152606081526103f9826032611e8b565b60408051602081019091526060815281600003611f3357611f2c836000611e8b565b90506103f9565b6000611f3e83612153565b60f8600382901b169390931b929050611f588160206132e2565b9050611f6f611f688260006132fb565b8590611e8b565b508351805161200090611f869060ff851690612ab0565b1115611fbe576040517fec031c1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516020818301019490945292019091525090565b6040805160208101909152606081526103f9826046611e8b565b6040805160208101909152606081526103f9826033611e8b565b60006120c1565b811a6000602f8211603a8310161561204957507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd081016103f9565b6047821060408311161561208057507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc981016103f9565b606782106060831116156120b757507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa981016103f9565b5061010092915050565b506001838201828216156120fd576120db6000865161200e565b80855360018601955060018501945060ff8111156120fb57600092508195505b505b8085101561214b57845161211260018261200e565b61211d60008361200e565b60041b17905060ff81111561213657600092505061214b565b808553506002850194506001840193506120fd565b509392505050565b60007001000000000000000000000000000000008210156121795760809190911b906010175b78010000000000000000000000000000000000000000000000008210156121a55760409190911b906008175b7c01000000000000000000000000000000000000000000000000000000008210156121d55760209190911b906004175b7e010000000000000000000000000000000000000000000000000000000000008210156122075760109190911b906002175b7f0100000000000000000000000000000000000000000000000000000000000000821015612233576001175b919050565b82805482825590600052602060002090810192821561227e579160200282015b8281111561227e578251829061226e9082613363565b5091602001919060010190612258565b506117a29291505b808211156117a257600061229a82826122a3565b50600101612286565b5080546122af90612f86565b6000825580601f106122bf575050565b601f01602090049060005260206000209081019061103791905b808211156117a257600081556001016122d9565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461223357600080fd5b60006020828403121561232f57600080fd5b6117e8826122ed565b73ffffffffffffffffffffffffffffffffffffffff8116811461103757600080fd5b60006020828403121561236c57600080fd5b81356117e881612338565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156123c9576123c9612377565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561241657612416612377565b604052919050565b600067ffffffffffffffff82111561243857612438612377565b5060051b60200190565b600082601f83011261245357600080fd5b81356124666124618261241e565b6123cf565b8082825260208201915060208360051b86010192508583111561248857600080fd5b602085015b838110156124ae5780356124a081612338565b83526020928301920161248d565b5095945050505050565b60ff8116811461103757600080fd5b8035612233816124b8565b600080604083850312156124e557600080fd5b823567ffffffffffffffff8111156124fc57600080fd5b61250885828601612442565b9250506020830135612519816124b8565b809150509250929050565b60005b8381101561253f578181015183820152602001612527565b50506000910152565b60008151808452612560816020860160208601612524565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208501945060208160051b8301016020850160005b83811015612600577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08584030188526125ea838351612548565b60209889019890935091909101906001016125b0565b50909695505050505050565b6020815260006117e86020830184612592565b600067ffffffffffffffff82111561263957612639612377565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006126736124618461261f565b905082815283838301111561268757600080fd5b828260208301376000602084830101529392505050565b600082601f8301126126af57600080fd5b6117e883833560208501612665565b60008083601f8401126126d057600080fd5b50813567ffffffffffffffff8111156126e857600080fd5b60208301915083602082850101111561177357600080fd5b6000806000806060858703121561271657600080fd5b843567ffffffffffffffff81111561272d57600080fd5b8501601f8101871361273e57600080fd5b803561274c6124618261241e565b8082825260208201915060208360051b85010192508983111561276e57600080fd5b602084015b838110156127b057803567ffffffffffffffff81111561279257600080fd5b6127a18c60208389010161269e565b84525060209283019201612773565b5096506127c392505050602086016124c7565b9250604085013567ffffffffffffffff8111156127df57600080fd5b6127eb878288016126be565b95989497509550505050565b6020815260006117e86020830184612548565b600082601f83011261281b57600080fd5b81356128296124618261241e565b8082825260208201915060208360051b86010192508583111561284b57600080fd5b602085015b838110156124ae57803567ffffffffffffffff81111561286f57600080fd5b8601603f8101881361288057600080fd5b61289288602083013560408401612665565b84525060209283019201612850565b6000602082840312156128b357600080fd5b813567ffffffffffffffff8111156128ca57600080fd5b610cfa8482850161280a565b600080600080604085870312156128ec57600080fd5b843567ffffffffffffffff81111561290357600080fd5b61290f878288016126be565b909550935050602085013567ffffffffffffffff8111156127df57600080fd5b60006020828403121561294157600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082601f83011261298857600080fd5b815160208301600061299c6124618461261f565b90508281528583830111156129b057600080fd5b6129be836020830184612524565b95945050505050565b6000602082840312156129d957600080fd5b815167ffffffffffffffff8111156129f057600080fd5b610cfa84828501612977565b60008060008060808587031215612a1257600080fd5b843567ffffffffffffffff811115612a2957600080fd5b612a3587828801612442565b945050602085013567ffffffffffffffff811115612a5257600080fd5b612a5e8782880161280a565b935050604085013591506060850135612a76816124b8565b939692955090935050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103f9576103f9612a81565b80357fffffffff000000000000000000000000000000000000000000000000000000008116906004841015612b22577fffffffff00000000000000000000000000000000000000000000000000000000808560040360031b1b82161691505b5092915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610cfa602083018486612b29565b805160208201517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000811691906014821015612beb577fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808360140360031b1b82161692505b5050919050565b60008085851115612c0257600080fd5b83861115612c0f57600080fd5b5050820193919092039150565b60008060408385031215612c2f57600080fd5b50508035926020909101359150565b803561223381612338565b600060208284031215612c5b57600080fd5b6040516020810167ffffffffffffffff81118282101715612c7e57612c7e612377565b604052905080823567ffffffffffffffff811115612c9b57600080fd5b612ca78582860161269e565b8252505092915050565b600060208284031215612cc357600080fd5b813567ffffffffffffffff811115612cda57600080fd5b820160a08185031215612cec57600080fd5b612cf46123a6565b612cfd82612c3e565b8152602082013567ffffffffffffffff811115612d1957600080fd5b612d258682850161269e565b602083015250604082013567ffffffffffffffff811115612d4557600080fd5b612d5186828501612c49565b604083015250612d63606083016122ed565b6060820152608082013567ffffffffffffffff811115612d8257600080fd5b612d8e8682850161269e565b608083015250949350505050565b6000815160208452610cfa6020850182612548565b606081526000612dc46060830187612548565b8281036020840152612dd68187612d9c565b90508281036040840152612deb818587612b29565b979650505050505050565b8051612233816124b8565b60008060408385031215612e1457600080fd5b825167ffffffffffffffff811115612e2b57600080fd5b8301601f81018513612e3c57600080fd5b8051612e4a6124618261241e565b8082825260208201915060208360051b850101925087831115612e6c57600080fd5b602084015b83811015612eae57805167ffffffffffffffff811115612e9057600080fd5b612e9f8a602083890101612977565b84525060209283019201612e71565b509450612ec19250505060208401612df6565b90509250929050565b6000606082016060835280865180835260808501915060808160051b86010192506020880160005b82811015612f41577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80878603018452612f2c858351612548565b94506020938401939190910190600101612ef2565b5050505060ff851660208401528281036040840152612f608185612548565b9695505050505050565b60008251612f7c818460208701612524565b9190910192915050565b600181811c90821680612f9a57607f821691505b6020821081036115a3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b818103818111156103f9576103f9612a81565b60808082528551908201819052600090602087019060a0840190835b8181101561303657835173ffffffffffffffffffffffffffffffffffffffff16835260209384019390920191600101613002565b5050838103602085015261304a8188612592565b9250505083604083015260ff8316606083015295945050505050565b60006020828403121561307857600080fd5b815167ffffffffffffffff81111561308f57600080fd5b8201601f810184136130a057600080fd5b80516130ae6124618261241e565b8082825260208201915060208360051b8501019250868311156130d057600080fd5b602084015b8381101561311257805167ffffffffffffffff8111156130f457600080fd5b61310389602083890101612977565b845250602092830192016130d5565b509695505050505050565b6040815260006131306040830185612548565b82810360208401526129be8185612d9c565b6020815273ffffffffffffffffffffffffffffffffffffffff82511660208201526000602083015160a0604084015261317e60c0840182612548565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160608501526131b98282612d9c565b9150507fffffffff00000000000000000000000000000000000000000000000000000000606085015116608084015260808401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160a08501526129be8282612548565b73ffffffffffffffffffffffffffffffffffffffff8616815260a06020820152600061325060a0830187612592565b82810360408401526132628187612548565b90507fffffffff0000000000000000000000000000000000000000000000000000000085166060840152828103608084015261329e8185612548565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036132db576132db612a81565b5060010190565b60ff82811682821603908111156103f9576103f9612a81565b60ff81811683821601908111156103f9576103f9612a81565b601f82111561335e57806000526020600020601f840160051c8101602085101561333b5750805b601f840160051c820191505b8181101561335b5760008155600101613347565b50505b505050565b815167ffffffffffffffff81111561337d5761337d612377565b6133918161338b8454612f86565b84613314565b6020601f8211600181146133e357600083156133ad5750848201515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b17845561335b565b6000848152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08516915b828110156134315787850151825560209485019460019092019101613411565b508482101561346d57868401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b60f8161c191681555b50505050600190811b0190555056fea26469706673582212207df73955a4cd1875e4422b5318e0811990c250304fd8716475d4a094f79a568a64736f6c634300081a0033",
  "devdoc": {
    "errors": {
      "DNSDecodingFailed(bytes)": [
        {
          "details": "The DNS-encoded name is malformed."
        }
      ],
      "OwnableInvalidOwner(address)": [
        {
          "details": "The owner is not a valid owner account. (eg. `address(0)`)"
        }
      ],
      "OwnableUnauthorizedAccount(address)": [
        {
          "details": "The caller account is not authorized to perform an operation."
        }
      ],
      "UnreachableName(bytes)": [
        {
          "details": "Error selector: `0x5fe9a5df`"
        }
      ],
      "UnsupportedResolverProfile(bytes4)": [
        {
          "details": "Error selector: `0x7b1c461b`"
        }
      ]
    },
    "kind": "dev",
    "methods": {
      "owner()": {
        "details": "Returns the address of the current owner."
      },
      "renounceOwnership()": {
        "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner."
      },
      "resolve(bytes,bytes)": {
        "details": "This function may execute over multiple steps.",
        "params": {
          "data": "The resolution data, as specified in ENSIP-10.",
          "name": "The reverse name to resolve, in normalised and DNS-encoded form."
        },
        "returns": {
          "result": "The encoded response for the requested profile."
        }
      },
      "resolveNameCallback(bytes[],uint8,bytes)": {
        "details": "CCIP-Read callback for `_resolveName()` (step 2 of 2).",
        "params": {
          "extraData": "The contextual data passed from `_resolveName()`.",
          "values": "The outputs for `GatewayRequest` (1 name)."
        },
        "returns": {
          "result": "The abi-encoded name for the given address."
        }
      },
      "resolveNames(address[],uint8)": {
        "details": "This function may execute over multiple steps.",
        "params": {
          "addrs": "The addresses to resolve.",
          "perPage": "The maximum number of addresses to resolve per call.                Ignored if this function does not revert `OffchainLookup`."
        },
        "returns": {
          "names": "The resolved names."
        }
      },
      "resolveNamesCallback(bytes[],uint8,bytes)": {
        "details": "CCIP-Read callback for `_resolveNames()` (step 2 of 2).      Recursive if there are still addresses to resolve.",
        "params": {
          "extraData": "The contextual data passed from `_resolveNames()`.",
          "values": "The outputs for `GatewayRequest` (N names)."
        },
        "returns": {
          "names": "The resolved names."
        }
      },
      "setGatewayURLs(string[])": {
        "params": {
          "gateways": "The new gateway URLs."
        }
      },
      "setGatewayVerifier(address)": {
        "params": {
          "verifier": "The new verifier contract."
        }
      },
      "supportsInterface(bytes4)": {
        "details": "See {IERC165-supportsInterface}."
      },
      "transferOwnership(address)": {
        "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
      }
    },
    "title": "Chain Reverse Resolver",
    "version": 1
  },
  "userdoc": {
    "errors": {
      "UnreachableName(bytes)": [
        {
          "notice": "`name` is not a valid DNS-encoded ENSIP-19 reverse name or namespace."
        }
      ],
      "UnsupportedResolverProfile(bytes4)": [
        {
          "notice": "`resolve()` was called with a profile other than `name()` or `addr(*)`."
        }
      ]
    },
    "events": {
      "GatewayURLsChanged(string[])": {
        "notice": "Emitted when the gateway URLs are changed."
      },
      "GatewayVerifierChanged(address)": {
        "notice": "Emitted when the gateway verifier is changed."
      }
    },
    "kind": "user",
    "methods": {
      "chainId()": {
        "notice": "The EVM Chain ID corresponding to the `coinType`."
      },
      "coinType()": {
        "notice": "The coin type for the resolver."
      },
      "defaultRegistrar()": {
        "notice": "The reverse registrar contract for \"default.reverse\"."
      },
      "gatewayURLs(uint256)": {
        "notice": "Gateway URLs for the verifier contract."
      },
      "gatewayVerifier()": {
        "notice": "The verifier contract for the L2 chain."
      },
      "l2Registrar()": {
        "notice": "The reverse registrar address on the L2 chain."
      },
      "resolve(bytes,bytes)": {
        "notice": "Resolves the following profiles according to ENSIP-10:         - `name()` if `name` is an ENSIP-19 reverse name of an EVM address for `coinType`.         - `addr(*) = registrar` if `name` is an ENSIP-19 reverse namespace for `coinType`.         Callers should enable EIP-3668."
      },
      "resolveNames(address[],uint8)": {
        "notice": "Resolve multiple EVM addresses to names.         Callers should enable EIP-3668."
      },
      "setGatewayURLs(string[])": {
        "notice": "Set gateway URLs."
      },
      "setGatewayVerifier(address)": {
        "notice": "Set the verifier contract."
      }
    },
    "notice": "Reverses an EVM address using the first non-null response from the following sources:         1. `L2ReverseRegistrar` on L2 chain via Unruggable Gateway         2. `IStandaloneReverseRegistrar` for \"default.reverse\"",
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 446,
        "contract": "contracts/reverseResolver/ChainReverseResolver.sol:ChainReverseResolver",
        "label": "_owner",
        "offset": 0,
        "slot": "0",
        "type": "t_address"
      },
      {
        "astId": 27914,
        "contract": "contracts/reverseResolver/ChainReverseResolver.sol:ChainReverseResolver",
        "label": "gatewayVerifier",
        "offset": 0,
        "slot": "1",
        "type": "t_contract(IGatewayVerifier)11457"
      },
      {
        "astId": 27918,
        "contract": "contracts/reverseResolver/ChainReverseResolver.sol:ChainReverseResolver",
        "label": "gatewayURLs",
        "offset": 0,
        "slot": "2",
        "type": "t_array(t_string_storage)dyn_storage"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_array(t_string_storage)dyn_storage": {
        "base": "t_string_storage",
        "encoding": "dynamic_array",
        "label": "string[]",
        "numberOfBytes": "32"
      },
      "t_contract(IGatewayVerifier)11457": {
        "encoding": "inplace",
        "label": "contract IGatewayVerifier",
        "numberOfBytes": "20"
      },
      "t_string_storage": {
        "encoding": "bytes",
        "label": "string",
        "numberOfBytes": "32"
      }
    }
  }
}