├── src
├── hooks
│ ├── index.ts
│ └── useContracts
│ │ └── index.ts
├── contexts
│ ├── index.ts
│ └── ContractsContext
│ │ └── index.tsx
├── react-app-env.d.ts
├── assets
│ ├── edit.png
│ ├── ethlogo.png
│ ├── question.png
│ └── polygonlogo.png
├── artifacts
│ └── contracts
│ │ └── Domains.sol
│ │ ├── Domains.dbg.json
│ │ └── Domains.json
├── components
│ ├── index.ts
│ ├── Spinner
│ │ ├── index.tsx
│ │ └── styles.ts
│ ├── Modal
│ │ ├── index.tsx
│ │ └── styles.ts
│ ├── Header
│ │ ├── index.tsx
│ │ └── styles.ts
│ ├── Button
│ │ └── index.ts
│ └── Form
│ │ ├── styles.ts
│ │ └── index.tsx
├── setupTests.ts
├── App.tsx
├── styles.ts
├── constants
│ └── index.ts
├── index.css
├── reportWebVitals.ts
├── index.tsx
├── utils
│ └── networks.ts
└── types
│ └── index.ts
├── public
├── robots.txt
├── favicon.ico
├── logo192.png
├── logo512.png
├── manifest.json
└── index.html
├── docs
├── main.js.LICENSE.txt
└── index.html
├── .gitignore
├── README.md
├── tsconfig.json
├── scripts
├── run.js
└── deploy.js
├── hardhat.config.js
├── contracts
├── libraries
│ ├── StringUtils.sol
│ └── Base64.sol
└── Domains.sol
└── package.json
/src/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./useContracts";
2 |
--------------------------------------------------------------------------------
/src/contexts/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./ContractsContext";
2 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pablopoggiog/polygon-name-service/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pablopoggiog/polygon-name-service/HEAD/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pablopoggiog/polygon-name-service/HEAD/public/logo512.png
--------------------------------------------------------------------------------
/src/assets/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pablopoggiog/polygon-name-service/HEAD/src/assets/edit.png
--------------------------------------------------------------------------------
/src/assets/ethlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pablopoggiog/polygon-name-service/HEAD/src/assets/ethlogo.png
--------------------------------------------------------------------------------
/src/assets/question.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pablopoggiog/polygon-name-service/HEAD/src/assets/question.png
--------------------------------------------------------------------------------
/src/assets/polygonlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pablopoggiog/polygon-name-service/HEAD/src/assets/polygonlogo.png
--------------------------------------------------------------------------------
/docs/main.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vue.js v2.6.14
3 | * (c) 2014-2021 Evan You
4 | * Released under the MIT License.
5 | */
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
3 | .env.local
4 | coverage
5 | coverage.json
6 | typechain
7 |
8 | #Hardhat files
9 | cache
10 |
--------------------------------------------------------------------------------
/src/artifacts/contracts/Domains.sol/Domains.dbg.json:
--------------------------------------------------------------------------------
1 | {
2 | "_format": "hh-sol-dbg-1",
3 | "buildInfo": "../../build-info/9a36ac6a828954ecb5bf73c69627ec38.json"
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./Form";
2 | export * from "./Header";
3 | export * from "./Button";
4 | export * from "./Spinner";
5 | export * from "./Modal";
6 |
--------------------------------------------------------------------------------
/src/hooks/useContracts/index.ts:
--------------------------------------------------------------------------------
1 | import { useContext } from "react";
2 | import { ContractsContext } from "src/contexts";
3 |
4 | export const useContracts = () => useContext(ContractsContext);
5 |
--------------------------------------------------------------------------------
/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
Hardhat Docgen
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { Form, Header } from "src/components";
2 | import { Container } from "./styles";
3 |
4 | const App = () => {
5 | return (
6 |
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default App;
14 |
--------------------------------------------------------------------------------
/src/components/Spinner/index.tsx:
--------------------------------------------------------------------------------
1 | import { FunctionComponent } from "react";
2 | import { Loader } from "./styles";
3 |
4 | export const Spinner: FunctionComponent = () => (
5 |
6 |
7 |
8 |
9 |
10 | );
11 |
--------------------------------------------------------------------------------
/src/styles.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | export const Container = styled.div`
4 | display: flex;
5 | flex-direction: column;
6 | width: 100%;
7 | min-height: 100vh;
8 | background-color: #081018;
9 | color: white;
10 | align-items: center;
11 | `;
12 |
--------------------------------------------------------------------------------
/src/constants/index.ts:
--------------------------------------------------------------------------------
1 | // using String here not to enforce the type, but to avoid using "!" (the env vars could not exist, and the type of the contants would be string | undefined)
2 | export const CONTRACT_ADDRESS = String(process.env.REACT_APP_CONTRACT_ADDRESS);
3 |
4 | export const TLD = "zed";
5 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/Modal/index.tsx:
--------------------------------------------------------------------------------
1 | import { FunctionComponent } from "react";
2 | import { Background, Container, Content } from "./styles";
3 |
4 | interface ModalProps {
5 | content: string | JSX.Element;
6 | isOpen: boolean;
7 | }
8 |
9 | export const Modal: FunctionComponent = ({ content, isOpen }) => {
10 | return (
11 |
12 |
13 | {content}
14 |
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Basic Sample Hardhat Project
2 |
3 | This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts.
4 |
5 | Try running some of the following tasks:
6 |
7 | ```shell
8 | npx hardhat accounts
9 | npx hardhat compile
10 | npx hardhat clean
11 | npx hardhat test
12 | npx hardhat node
13 | node scripts/sample-script.js
14 | npx hardhat help
15 | ```
16 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx",
22 | "baseUrl": ".",
23 | },
24 | "include": [
25 | "src"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import { ContractsProvider } from "src/contexts";
4 | import "./index.css";
5 | import App from "./App";
6 | import reportWebVitals from "./reportWebVitals";
7 |
8 | ReactDOM.render(
9 |
10 |
11 |
12 |
13 | ,
14 | document.getElementById("root")
15 | );
16 |
17 | // If you want to start measuring performance in your app, pass a function
18 | // to log results (for example: reportWebVitals(console.log))
19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
20 | reportWebVitals();
21 |
--------------------------------------------------------------------------------
/src/utils/networks.ts:
--------------------------------------------------------------------------------
1 | const networks = {
2 | "0x1": "Mainnet",
3 | "0x3": "Ropsten",
4 | "0x2a": "Kovan",
5 | "0x4": "Rinkeby",
6 | "0x5": "Goerli",
7 | "0x61": "BSC Testnet",
8 | "0x38": "BSC Mainnet",
9 | "0x89": "Polygon Mainnet",
10 | "0x13881": "Polygon Mumbai Testnet",
11 | "0xa86a": "AVAX Mainnet",
12 | };
13 |
14 | export const mumbaiNetwork = {
15 | chainId: "0x13881",
16 | chainName: "Polygon Mumbai Testnet",
17 | rpcUrls: ["https://rpc-mumbai.maticvigil.com/"],
18 | nativeCurrency: {
19 | name: "Mumbai Matic",
20 | symbol: "MATIC",
21 | decimals: 18,
22 | },
23 | blockExplorerUrls: ["https://mumbai.polygonscan.com/"],
24 | };
25 |
26 | export { networks };
27 |
--------------------------------------------------------------------------------
/src/components/Modal/styles.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | interface BackgroundProps {
4 | isOpen: boolean;
5 | }
6 |
7 | export const Background = styled.div`
8 | background: rgba(0, 0, 0, 0.7);
9 | position: fixed;
10 | bottom: 0;
11 | top: 0;
12 | right: 0;
13 | left: 0;
14 | width: 100vw;
15 | height: 100vh;
16 | z-index: 90;
17 | display: ${({ isOpen }) => (isOpen ? "flex" : "none")};
18 | align-items: center;
19 | justify-content: center;
20 | `;
21 |
22 | export const Container = styled.div`
23 | display: flex;
24 | flex-direction: column;
25 | color: white;
26 | border-radius: 5px;
27 | width: 80%;
28 | max-width: 500px;
29 | padding: 1em 1.4em;
30 | word-break: break-word;
31 | `;
32 |
33 | export const Content = styled.div`
34 | padding: 1em;
35 | `;
36 |
--------------------------------------------------------------------------------
/src/types/index.ts:
--------------------------------------------------------------------------------
1 | import { networks } from "src/utils/networks";
2 |
3 | declare global {
4 | interface Window {
5 | ethereum?: any;
6 | }
7 | }
8 |
9 | export interface IContractsContext {
10 | currentAccount: string;
11 | connectWallet: () => void;
12 | mintDomain: MintOrUpdateDomain;
13 | network: string;
14 | switchNetwork: () => void;
15 | updateDomain: MintOrUpdateDomain;
16 | mints: IRecord[];
17 | isLoadingDomains: boolean;
18 | }
19 |
20 | export type MintOrUpdateDomain = (params: {
21 | domain: string;
22 | record: string;
23 | setRecord: (record: string) => void;
24 | setDomain: (domain: string) => void;
25 | setIsLoading: (isLoading: boolean) => void;
26 | }) => void;
27 |
28 | export type Network = keyof typeof networks;
29 |
30 | export interface IRecord {
31 | id: number;
32 | name: string;
33 | record: any;
34 | owner: any;
35 | }
36 |
--------------------------------------------------------------------------------
/scripts/run.js:
--------------------------------------------------------------------------------
1 | const main = async () => {
2 | const domainContractFactory = await hre.ethers.getContractFactory("Domains");
3 | const TLD = "zed";
4 | const domainContract = await domainContractFactory.deploy(TLD);
5 | await domainContract.deployed();
6 |
7 | console.log("Contract deployed to:", domainContract.address);
8 |
9 | let txn = await domainContract.register("lord", {
10 | value: hre.ethers.utils.parseEther("0.3"),
11 | });
12 | await txn.wait();
13 |
14 | const address = await domainContract.getAddress("lord");
15 | console.log(`Owner of domain lord.${TLD}:`, address);
16 |
17 | const balance = await hre.ethers.provider.getBalance(domainContract.address);
18 | console.log("Contract balance:", hre.ethers.utils.formatEther(balance));
19 | };
20 |
21 | const runMain = async () => {
22 | try {
23 | await main();
24 | process.exit(0);
25 | } catch (error) {
26 | console.log(error);
27 | process.exit(1);
28 | }
29 | };
30 |
31 | runMain();
32 |
--------------------------------------------------------------------------------
/src/components/Spinner/styles.ts:
--------------------------------------------------------------------------------
1 | import styled, { keyframes } from "styled-components";
2 |
3 | const spin = keyframes`
4 | 0% {
5 | transform: rotate(0deg);
6 | }
7 |
8 | 50% {
9 | transform: rotate(180deg);
10 | opacity: 0.6;
11 | }
12 |
13 | 100% {
14 | transform: rotate(360deg);
15 | opacity: 1;
16 | }
17 | `;
18 |
19 | interface LoaderProps {
20 | inner?: boolean;
21 | innest?: boolean;
22 | }
23 |
24 | export const Loader = styled.div`
25 | border: 16px solid lightBlue;
26 | border-top: 16px solid rgba(255, 219, 220);
27 | border-radius: 50%;
28 | animation: ${spin} 2s linear infinite;
29 | margin: 0 auto;
30 | display: flex;
31 | align-items: center;
32 | justify-content: center;
33 | width: ${({ inner, innest }) => (inner ? "67px" : innest ? "15px" : "120px")};
34 | height: ${({ inner, innest }) =>
35 | inner ? "67px" : innest ? "15px" : "120px"};
36 | `;
37 |
--------------------------------------------------------------------------------
/hardhat.config.js:
--------------------------------------------------------------------------------
1 | require("@nomiclabs/hardhat-waffle");
2 | require("hardhat-docgen");
3 | require("dotenv").config();
4 |
5 | // This is a sample Hardhat task. To learn how to create your own go to
6 | // https://hardhat.org/guides/create-task.html
7 | task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
8 | const accounts = await hre.ethers.getSigners();
9 |
10 | for (const account of accounts) {
11 | console.log(account.address);
12 | }
13 | });
14 |
15 | // You need to export an object to set up your config
16 | // Go to https://hardhat.org/config/ to learn more
17 |
18 | /**
19 | * @type import('hardhat/config').HardhatUserConfig
20 | */
21 | module.exports = {
22 | solidity: "0.8.10",
23 | docgen: {
24 | path: "./docs",
25 | clear: true,
26 | runOnCompile: false,
27 | },
28 | paths: {
29 | artifacts: "./src/artifacts",
30 | },
31 | networks: {
32 | mumbai: {
33 | url: process.env.ALCHEMY_KEY,
34 | accounts: [process.env.PRIVATE_KEY],
35 | },
36 | },
37 | };
38 |
--------------------------------------------------------------------------------
/contracts/libraries/StringUtils.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | // Source:
3 | // https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/StringUtils.sol
4 | pragma solidity >=0.8.4;
5 |
6 | library StringUtils {
7 | /**
8 | * @dev Returns the length of a given string
9 | *
10 | * @param s The string to measure the length of
11 | * @return The length of the input string
12 | */
13 | function strlen(string memory s) internal pure returns (uint256) {
14 | uint256 len;
15 | uint256 i = 0;
16 | uint256 bytelength = bytes(s).length;
17 | for (len = 0; i < bytelength; len++) {
18 | bytes1 b = bytes(s)[i];
19 | if (b < 0x80) {
20 | i += 1;
21 | } else if (b < 0xE0) {
22 | i += 2;
23 | } else if (b < 0xF0) {
24 | i += 3;
25 | } else if (b < 0xF8) {
26 | i += 4;
27 | } else if (b < 0xFC) {
28 | i += 5;
29 | } else {
30 | i += 6;
31 | }
32 | }
33 | return len;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/components/Header/index.tsx:
--------------------------------------------------------------------------------
1 | import { FunctionComponent } from "react";
2 | import { useContracts } from "src/hooks";
3 | import polygonLogo from "src/assets/polygonlogo.png";
4 | import ethLogo from "src/assets/ethlogo.png";
5 | import question from "src/assets/question.png";
6 | import { Container, Title, Image, WalletStatus } from "./styles";
7 |
8 | export const Header: FunctionComponent = () => {
9 | const { currentAccount, network } = useContracts();
10 |
11 | return (
12 |
13 | 🏇 Zed Name Service 🏇
14 |
15 |
25 | {currentAccount ? (
26 |
27 | {" "}
28 | Wallet: {currentAccount.slice(0, 6)}...
29 | {currentAccount.slice(-4)}{" "}
30 |
31 | ) : (
32 | Not connected
33 | )}
34 |
35 |
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/src/components/Button/index.ts:
--------------------------------------------------------------------------------
1 | import styled, { keyframes } from "styled-components";
2 |
3 | const gradientAnimation = keyframes`
4 | 0% {
5 | background-position: 0% 50%;
6 | }
7 | 50% {
8 | background-position: 100% 50%;
9 | }
10 | 100% {
11 | background-position: 0% 50%;
12 | }
13 | }
14 | `;
15 |
16 | interface ButtonProps {
17 | disabled?: boolean;
18 | }
19 |
20 | export const Button = styled.button`
21 | border-radius: 1em;
22 | padding: 14px;
23 | cursor: ${({ disabled }) => !disabled && "pointer"};
24 | will-change: transform;
25 | background: ${({ disabled }) =>
26 | disabled
27 | ? "-webkit-linear-gradient(left, rgba(105, 105, 105), rgba(105, 105, 105, 0.1))"
28 | : "-webkit-linear-gradient(left, #a200d6, rgba(130, 71, 229, 0.6))"};
29 | background-size: 200% 200%;
30 | width: 100%;
31 | border: none;
32 | color: linear-gradient(left, #a200d6, rgba(130, 71, 229, 0.7));
33 | color: white;
34 | font-size: 1em;
35 | animation: ${gradientAnimation} 4s ease infinite;
36 | transition: 0.5s;
37 |
38 | &:hover {
39 | transform: ${({ disabled }) => !disabled && "scale(1.02)"};
40 | }
41 | `;
42 |
--------------------------------------------------------------------------------
/scripts/deploy.js:
--------------------------------------------------------------------------------
1 | const main = async () => {
2 | const domainContractFactory = await hre.ethers.getContractFactory("Domains");
3 | const TLD = "zed";
4 | const domainContract = await domainContractFactory.deploy(TLD);
5 | await domainContract.deployed();
6 |
7 | console.log("Contract deployed to:", domainContract.address);
8 |
9 | let txn = await domainContract.register("jors", {
10 | value: hre.ethers.utils.parseEther("0.3"),
11 | });
12 | await txn.wait();
13 | console.log(`Minted domain jors.${TLD}`);
14 |
15 | txn = await domainContract.setRecord("jors", `Am I a jors or a ${TLD}??`);
16 | await txn.wait();
17 | console.log(`Set record for jors.${TLD}`);
18 |
19 | const address = await domainContract.getAddress("jors");
20 | console.log("Owner of domain jors:", address);
21 |
22 | const balance = await hre.ethers.provider.getBalance(domainContract.address);
23 | console.log("Contract balance:", hre.ethers.utils.formatEther(balance));
24 | };
25 |
26 | const runMain = async () => {
27 | try {
28 | await main();
29 | process.exit(0);
30 | } catch (error) {
31 | console.log(error);
32 | process.exit(1);
33 | }
34 | };
35 |
36 | runMain();
37 |
--------------------------------------------------------------------------------
/src/components/Header/styles.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | export const Container = styled.header`
4 | display: flex;
5 | width: 100%;
6 | background-color: #081018;
7 | color: white;
8 | align-items: center;
9 | justify-content: space-around;
10 |
11 | @media (max-width: 768px) {
12 | flex-direction: column;
13 | font-size: 0.7em;
14 | }
15 |
16 | @media (max-width: 500px) {
17 | font-size: 0.6em;
18 | }
19 | `;
20 |
21 | export const Title = styled.h1`
22 | font-size: 2em;
23 | font-weight: 600;
24 | display: flex;
25 | background: black;
26 | border-radius: 16px;
27 | padding: 12px 20px;
28 | margin-right: 10%;
29 | text-align: center;
30 |
31 | @media (max-width: 768px) {
32 | padding: 2rem;
33 | margin: 1rem;
34 | }
35 | `;
36 |
37 | export const WalletStatus = styled.div`
38 | display: flex;
39 | align-items: center;
40 | justify-content: space-around;
41 | text-align: left;
42 | margin-left: 10%;
43 |
44 | @media (max-width: 768px) {
45 | padding: 2rem;
46 | margin: 1rem;
47 | }
48 | `;
49 |
50 | export const Image = styled.img`
51 | width: 20px;
52 | height: 20px;
53 | margin-right: 10px;
54 | `;
55 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "polygon-name-service",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "react-scripts start",
8 | "build": "react-scripts build",
9 | "test": "react-scripts test",
10 | "eject": "react-scripts eject"
11 | },
12 | "keywords": [],
13 | "author": "",
14 | "license": "ISC",
15 | "devDependencies": {
16 | "@nomiclabs/hardhat-ethers": "^2.0.5",
17 | "@nomiclabs/hardhat-waffle": "^2.0.2",
18 | "@types/styled-components": "^5.1.23",
19 | "chai": "^4.3.6",
20 | "ethereum-waffle": "^3.4.0",
21 | "ethers": "^5.5.4",
22 | "hardhat": "^2.8.4",
23 | "hardhat-docgen": "^1.3.0"
24 | },
25 | "dependencies": {
26 | "@openzeppelin/contracts": "^4.5.0",
27 | "@testing-library/jest-dom": "^5.16.2",
28 | "@testing-library/react": "^12.1.3",
29 | "@testing-library/user-event": "^13.5.0",
30 | "@types/jest": "^27.4.0",
31 | "@types/node": "^16.11.25",
32 | "@types/react": "^17.0.39",
33 | "@types/react-dom": "^17.0.11",
34 | "react": "^17.0.2",
35 | "react-dom": "^17.0.2",
36 | "react-scripts": "5.0.0",
37 | "styled-components": "^5.3.3",
38 | "typescript": "^4.5.5",
39 | "web-vitals": "^2.1.4"
40 | },
41 | "eslintConfig": {
42 | "extends": [
43 | "react-app",
44 | "react-app/jest"
45 | ]
46 | },
47 | "browserslist": {
48 | "production": [
49 | ">0.2%",
50 | "not dead",
51 | "not op_mini all"
52 | ],
53 | "development": [
54 | "last 1 chrome version",
55 | "last 1 firefox version",
56 | "last 1 safari version"
57 | ]
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Zed Name Service
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/contracts/libraries/Base64.sol:
--------------------------------------------------------------------------------
1 | /**
2 | *Submitted for verification at Etherscan.io on 2021-09-05
3 | */
4 |
5 | // SPDX-License-Identifier: MIT
6 |
7 | pragma solidity ^0.8.0;
8 |
9 | /// [MIT License]
10 | /// @title Base64
11 | /// @notice Provides a function for encoding some bytes in base64
12 | /// @author Brecht Devos
13 | library Base64 {
14 | bytes internal constant TABLE =
15 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
16 |
17 | /// @notice Encodes some bytes to the base64 representation
18 | function encode(bytes memory data) internal pure returns (string memory) {
19 | uint256 len = data.length;
20 | if (len == 0) return "";
21 |
22 | // multiply by 4/3 rounded up
23 | uint256 encodedLen = 4 * ((len + 2) / 3);
24 |
25 | // Add some extra buffer at the end
26 | bytes memory result = new bytes(encodedLen + 32);
27 |
28 | bytes memory table = TABLE;
29 |
30 | assembly {
31 | let tablePtr := add(table, 1)
32 | let resultPtr := add(result, 32)
33 |
34 | for {
35 | let i := 0
36 | } lt(i, len) {
37 |
38 | } {
39 | i := add(i, 3)
40 | let input := and(mload(add(data, i)), 0xffffff)
41 |
42 | let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
43 | out := shl(8, out)
44 | out := add(
45 | out,
46 | and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)
47 | )
48 | out := shl(8, out)
49 | out := add(
50 | out,
51 | and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)
52 | )
53 | out := shl(8, out)
54 | out := add(
55 | out,
56 | and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)
57 | )
58 | out := shl(224, out)
59 |
60 | mstore(resultPtr, out)
61 |
62 | resultPtr := add(resultPtr, 4)
63 | }
64 |
65 | switch mod(len, 3)
66 | case 1 {
67 | mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
68 | }
69 | case 2 {
70 | mstore(sub(resultPtr, 1), shl(248, 0x3d))
71 | }
72 |
73 | mstore(result, encodedLen)
74 | }
75 |
76 | return string(result);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/components/Form/styles.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | export const Container = styled.div`
4 | display: flex;
5 | flex-direction: column;
6 | align-items: center;
7 | justify-content: space-around;
8 | gap: 3em;
9 | height: 100%;
10 | padding: 2rem;
11 | width: 100%;
12 | box-sizing: border-box;
13 | `;
14 |
15 | export const FormBody = styled.div`
16 | display: flex;
17 | flex-direction: column;
18 | align-items: center;
19 | justify-content: center;
20 | gap: 3em;
21 | padding: 2rem;
22 | max-width: 310px;
23 | box-sizing: border-box;
24 | `;
25 |
26 | export const ButtonsContainer = styled.div`
27 | display: flex;
28 | align-items: center;
29 | justify-content: center;
30 | gap: 1em;
31 | width: 100%;
32 | `;
33 |
34 | export const InputContainer = styled.div`
35 | display: flex;
36 | align-items: center;
37 | justify-content: center;
38 | gap: 1em;
39 | background: black;
40 | border-radius: 8px;
41 | width: 100%;
42 |
43 | & > * {
44 | padding: 14px;
45 | font-size: 1em;
46 | color: white;
47 | background: black;
48 | border: none;
49 | border-radius: 8px;
50 | }
51 | `;
52 |
53 | export const Input = styled.input`
54 | width: 100%;
55 | `;
56 |
57 | export const SwitchNetwork = styled.div`
58 | display: flex;
59 | flex-direction: column;
60 | gap: 2rem;
61 |
62 | p {
63 | text-align: center;
64 | }
65 | `;
66 |
67 | // Domains
68 |
69 | export const DomainsContainer = styled.div`
70 | display: flex;
71 | flex-direction: column;
72 | justify-content: center;
73 | width: 100%;
74 | `;
75 |
76 | export const Subtitle = styled.p`
77 | text-align: center;
78 | `;
79 |
80 | export const DomainsList = styled.div`
81 | display: flex;
82 | justify-content: center;
83 | align-items: center;
84 | gap: 2em;
85 | flex-wrap: wrap;
86 | padding: 2em 0;
87 | `;
88 |
89 | export const Domain = styled.div`
90 | min-width: 115px;
91 | display: flex;
92 | flex-direction: column;
93 | justify-content: center;
94 | align-items: center;
95 | background: rgba(130, 71, 229, 0.4);
96 | border-radius: 7px;
97 | padding: 0.8em;
98 | `;
99 |
100 | export const Row = styled.div`
101 | display: flex;
102 | justify-content: center;
103 | align-items: center;
104 | gap: 1em;
105 | width: 100%;
106 | `;
107 |
108 | export const Link = styled.a`
109 | color: white !important;
110 | `;
111 |
112 | export const Name = styled.p``;
113 |
114 | export const Image = styled.img``;
115 |
116 | export const EditButton = styled.button`
117 | height: 30px;
118 | width: 30px;
119 | border-radius: 7px;
120 | background: transparent;
121 | border: none;
122 | cursor: pointer;
123 | transition: 0.5s;
124 |
125 | &:hover {
126 | transform: scale(1.02);
127 | }
128 | `;
129 |
--------------------------------------------------------------------------------
/src/components/Form/index.tsx:
--------------------------------------------------------------------------------
1 | import { FunctionComponent, useState } from "react";
2 | import { useContracts } from "src/hooks";
3 | import { Button, Spinner, Modal } from "src/components";
4 | import { CONTRACT_ADDRESS, TLD } from "src/constants";
5 | import editIcon from "src/assets/edit.png";
6 | import {
7 | Container,
8 | FormBody,
9 | ButtonsContainer,
10 | InputContainer,
11 | Input,
12 | SwitchNetwork,
13 | DomainsContainer,
14 | Subtitle,
15 | DomainsList,
16 | Domain,
17 | Link,
18 | Name,
19 | Image,
20 | Row,
21 | EditButton,
22 | } from "./styles";
23 |
24 | export const Form: FunctionComponent = () => {
25 | const [domain, setDomain] = useState("");
26 | const [record, setRecord] = useState("");
27 | const [isLoading, setIsLoading] = useState(false);
28 | const [isEditing, setIsEditing] = useState(false);
29 |
30 | const {
31 | mintDomain,
32 | network,
33 | switchNetwork,
34 | currentAccount,
35 | connectWallet,
36 | updateDomain,
37 | mints,
38 | isLoadingDomains,
39 | } = useContracts();
40 |
41 | const handleMint = () =>
42 | mintDomain({
43 | domain,
44 | record,
45 | setRecord,
46 | setDomain,
47 | setIsLoading,
48 | });
49 |
50 | const handleUpdateDomain = () =>
51 | updateDomain({
52 | domain,
53 | record,
54 | setRecord,
55 | setDomain,
56 | setIsLoading,
57 | });
58 |
59 | const editRecord = (name: string) => {
60 | console.log("Editing record for", name);
61 | setIsEditing(true);
62 | setDomain(name);
63 | };
64 |
65 | return (
66 |
67 |
68 | {currentAccount ? (
69 | network !== "Polygon Mumbai Testnet" ? (
70 |
71 | Please connect to the Polygon Mumbai Testnet
72 |
73 |
74 | ) : (
75 | <>
76 |
77 | setDomain(e.target.value)}
83 | />
84 | .{TLD}
85 |
86 |
87 |
88 | setRecord(e.target.value)}
94 | />
95 |
96 |
97 |
98 | {isEditing ? (
99 | <>
100 |
103 |
104 | >
105 | ) : (
106 |
109 | )}
110 |
111 | >
112 | )
113 | ) : (
114 |
115 | )}
116 |
117 |
118 | {isLoadingDomains && }
119 |
120 | {currentAccount && mints.length > 0 && (
121 |
122 | Recently minted domains!
123 |
124 | {mints.map(({ id, name, owner, record }) => (
125 |
126 |
127 |
132 |
133 | {name}.{TLD}
134 |
135 |
136 | {/* Only editable being the owner */}
137 | {owner.toLowerCase() === currentAccount.toLowerCase() && (
138 | editRecord(name)}>
139 |
140 |
141 | )}
142 |
143 | {record}
144 |
145 | ))}
146 |
147 |
148 | )}
149 |
150 | } />
151 |
152 | );
153 | };
154 |
--------------------------------------------------------------------------------
/src/contexts/ContractsContext/index.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | FunctionComponent,
3 | createContext,
4 | useState,
5 | useEffect,
6 | useCallback,
7 | } from "react";
8 | import { ethers } from "ethers";
9 | import {
10 | IContractsContext,
11 | MintOrUpdateDomain,
12 | Network,
13 | IRecord,
14 | } from "src/types";
15 | import { CONTRACT_ADDRESS } from "src/constants";
16 | import DOMAINS from "src/artifacts/contracts/Domains.sol/Domains.json";
17 | import { networks, mumbaiNetwork } from "src/utils/networks";
18 |
19 | const { ethereum } = window;
20 |
21 | export const ContractsContext = createContext({
22 | currentAccount: "",
23 | connectWallet: () => {
24 | return;
25 | },
26 | mintDomain: () => {
27 | return;
28 | },
29 | network: "0x89",
30 | switchNetwork: () => {
31 | return;
32 | },
33 | updateDomain: () => {
34 | return;
35 | },
36 | mints: [],
37 | isLoadingDomains: false,
38 | });
39 |
40 | export const ContractsProvider: FunctionComponent = ({ children }) => {
41 | const [currentAccount, setCurrentAccount] = useState("");
42 | const [network, setNetwork] = useState("");
43 | const [mints, setMints] = useState([]);
44 | const [isLoadingDomains, setIsLoadingDomains] = useState(false);
45 |
46 | const checkIfWalletIsConnected = useCallback(async () => {
47 | const accounts = await ethereum.request({
48 | method: "eth_accounts",
49 | });
50 |
51 | if (accounts.length !== 0) {
52 | const account = accounts[0];
53 | console.log("Found an authorized account:", account);
54 | setCurrentAccount(account);
55 | } else {
56 | console.log("No authorized account found");
57 | }
58 |
59 | const chainId: Network = await ethereum.request({
60 | method: "eth_chainId",
61 | });
62 | setNetwork(networks[chainId] || "");
63 |
64 | ethereum.on("chainChanged", handleChainChanged);
65 |
66 | function handleChainChanged(_chainId: Network | string) {
67 | window.location.reload();
68 | }
69 |
70 | fetchMints();
71 | }, []);
72 |
73 | const connectWallet = async () => {
74 | try {
75 | if (!ethereum) {
76 | alert("Get MetaMask -> https://metamask.io/");
77 | return;
78 | }
79 |
80 | // Fancy method to request access to account.
81 | const accounts = await ethereum.request({
82 | method: "eth_requestAccounts",
83 | });
84 |
85 | // Boom! This should print out public address once we authorize Metamask.
86 | console.log("Connected", accounts[0]);
87 | setCurrentAccount(accounts[0]);
88 |
89 | fetchMints();
90 | } catch (error) {
91 | console.log(error);
92 | }
93 | };
94 |
95 | const mintDomain: MintOrUpdateDomain = async ({
96 | domain,
97 | record,
98 | setRecord,
99 | setDomain,
100 | setIsLoading,
101 | }) => {
102 | if (!domain || !record) {
103 | return;
104 | }
105 |
106 | if (domain.length < 3) {
107 | alert("Domain must be at least 3 characters long");
108 | return;
109 | }
110 |
111 | setIsLoading(true);
112 |
113 | const price =
114 | domain.length === 3 ? "0.5" : domain.length === 4 ? "0.3" : "0.1";
115 | console.log("Minting domain", domain, "with price", price);
116 |
117 | try {
118 | if (ethereum) {
119 | const provider = new ethers.providers.Web3Provider(ethereum);
120 | const signer = provider.getSigner();
121 | const contract = new ethers.Contract(
122 | CONTRACT_ADDRESS,
123 | DOMAINS.abi,
124 | signer
125 | );
126 |
127 | console.log("Going to pop wallet now to pay gas...");
128 |
129 | let tx = await contract.register(domain, {
130 | value: ethers.utils.parseEther(price),
131 | });
132 |
133 | const receipt = await tx.wait();
134 |
135 | // Checks if the transaction was successfully completed
136 | if (receipt.status === 1) {
137 | console.log(
138 | "Domain minted! https://mumbai.polygonscan.com/tx/" + tx.hash
139 | );
140 |
141 | tx = await contract.setRecord(domain, record);
142 | await tx.wait();
143 |
144 | console.log(
145 | "Record set! https://mumbai.polygonscan.com/tx/" + tx.hash
146 | );
147 |
148 | fetchMints();
149 |
150 | setRecord("");
151 | setDomain("");
152 | } else {
153 | alert("Transaction failed! Please try again");
154 | }
155 | }
156 | } catch (error) {
157 | console.log(error);
158 | }
159 |
160 | setIsLoading(false);
161 | };
162 |
163 | const switchNetwork = async () => {
164 | if (ethereum) {
165 | try {
166 | // Switch to the Mumbai testnet
167 | await ethereum.request({
168 | method: "wallet_switchEthereumChain",
169 | params: [{ chainId: mumbaiNetwork.chainId }],
170 | });
171 | } catch (error: any) {
172 | // This error code means that the chain we want has not been added to MetaMask
173 | // In this case we ask the user to add it to their MetaMask
174 | if (error.code === 4902) {
175 | try {
176 | await ethereum.request({
177 | method: "wallet_addEthereumChain",
178 | params: [mumbaiNetwork],
179 | });
180 | } catch (error) {
181 | console.log(error);
182 | }
183 | }
184 | console.log(error);
185 | }
186 | } else {
187 | // If window.ethereum is not found then MetaMask is not installed
188 | alert(
189 | "MetaMask is not installed. Please install it to use this app: https://metamask.io/download.html"
190 | );
191 | }
192 | };
193 |
194 | const fetchMints = async () => {
195 | setIsLoadingDomains(true);
196 |
197 | try {
198 | if (ethereum) {
199 | const provider = new ethers.providers.Web3Provider(ethereum);
200 | const signer = provider.getSigner();
201 | const contract = new ethers.Contract(
202 | CONTRACT_ADDRESS,
203 | DOMAINS.abi,
204 | signer
205 | );
206 |
207 | const names: string[] = await contract.getAllNames();
208 |
209 | // For each name, gets the record and the address
210 | const mintRecords: IRecord[] = await Promise.all(
211 | names.map(async (name) => {
212 | const mintRecord = await contract.records(name);
213 | const owner = await contract.domains(name);
214 | return {
215 | id: names.indexOf(name),
216 | name: name,
217 | record: mintRecord,
218 | owner: owner,
219 | };
220 | })
221 | );
222 |
223 | console.log("MINTS FETCHED ", mintRecords);
224 | setMints(mintRecords);
225 | }
226 | } catch (error) {
227 | console.log(error);
228 | }
229 |
230 | setIsLoadingDomains(false);
231 | };
232 |
233 | const updateDomain: MintOrUpdateDomain = async ({
234 | record,
235 | domain,
236 | setIsLoading,
237 | setRecord,
238 | setDomain,
239 | }) => {
240 | if (!record || !domain) return;
241 |
242 | setIsLoading(true);
243 | console.log("Updating domain", domain, "with record", record);
244 |
245 | try {
246 | if (ethereum) {
247 | const provider = new ethers.providers.Web3Provider(ethereum);
248 | const signer = provider.getSigner();
249 | const contract = new ethers.Contract(
250 | CONTRACT_ADDRESS,
251 | DOMAINS.abi,
252 | signer
253 | );
254 |
255 | const tx = await contract.setRecord(domain, record);
256 | await tx.wait();
257 | console.log("Record set https://mumbai.polygonscan.com/tx/" + tx.hash);
258 |
259 | fetchMints();
260 | setRecord("");
261 | setDomain("");
262 | }
263 | } catch (error) {
264 | console.log(error);
265 | }
266 | setIsLoading(false);
267 | };
268 |
269 | useEffect(() => {
270 | checkIfWalletIsConnected();
271 | }, [checkIfWalletIsConnected]);
272 |
273 | return (
274 |
286 | {children}
287 |
288 | );
289 | };
290 |
--------------------------------------------------------------------------------
/contracts/Domains.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: UNLICENSED
2 |
3 | pragma solidity ^0.8.10;
4 |
5 | import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
6 | import "@openzeppelin/contracts/utils/Counters.sol";
7 | import "hardhat/console.sol";
8 |
9 | import {StringUtils} from "./libraries/StringUtils.sol";
10 | import {Base64} from "./libraries/Base64.sol";
11 |
12 | /**
13 | * @title Domains
14 | * @notice - Contract that creates and stores domains in the blockchain.
15 | * @dev - It inherits from `ERC721URIStorage`.
16 | */
17 | contract Domains is ERC721URIStorage {
18 | using Counters for Counters.Counter;
19 | Counters.Counter private _tokenIds;
20 |
21 | /**
22 | * @notice - Who deployed the contract.
23 | */
24 | address public owner;
25 |
26 | /**
27 | * @notice - Stores the domain's TLD.
28 | */
29 | string public tld;
30 |
31 | string svgPartOne =
32 | '";
34 |
35 | /**
36 | * @notice - Stores addresses of the owners of all the domains, indexed by domain's name.
37 | */
38 | mapping(string => address) public domains;
39 |
40 | /**
41 | * @notice - Stores all the domains' names, indexed by token ID.
42 | */
43 | mapping(uint256 => string) public names;
44 |
45 | /**
46 | * @notice - Stores records for domains, indexed by domain's name.
47 | */
48 | mapping(string => string) public records;
49 |
50 | /**
51 | * @dev - Sets the value of `owner` to who's deploying the contract, `tld` to the param `_tld_` and logs it to the console.
52 | * @param _tld - The value to be set for `tld`.
53 | */
54 | constructor(string memory _tld)
55 | payable
56 | ERC721("Zed Run Name Service", "ZNS")
57 | {
58 | owner = payable(msg.sender);
59 | tld = _tld;
60 | console.log("%s name service deployed", _tld);
61 | }
62 |
63 | /**
64 | * @notice - Gives the price of a domain based on its name's length.
65 | * @param name - The name for the domain to be registered.
66 | * @return - The price for that domain.
67 | */
68 | function getPrice(string calldata name) public pure returns (uint256) {
69 | uint256 len = StringUtils.strlen(name);
70 | require(len > 0);
71 | if (len == 3) {
72 | return 5 * 10**17; // 0.5 MATIC
73 | } else if (len == 4) {
74 | return 3 * 10**17;
75 | } else {
76 | return 1 * 10**17;
77 | }
78 | }
79 |
80 | /**
81 | * @dev - Requires the caller to be the contract's owner.
82 | * @param name - The name for the domain to be validated.
83 | */
84 | modifier isValidName(string calldata name) {
85 | require(
86 | StringUtils.strlen(name) >= 3 && StringUtils.strlen(name) <= 10,
87 | "Names can have between 3 and 10 chars"
88 | );
89 | _;
90 | }
91 |
92 | /**
93 | * @notice - Registers a domain name after checking it's valid, mapping it to the caller's address.
94 | * @param name - The name for the domain to be registered.
95 | */
96 | function register(string calldata name) public payable isValidName(name) {
97 | require(domains[name] == address(0), "Name is already in use");
98 |
99 | uint256 _price = getPrice(name);
100 |
101 | require(msg.value >= _price, "Not enough MATIC paid");
102 |
103 | // Combines the name passed into the function with the TLD
104 | string memory _name = string(abi.encodePacked(name, ".", tld));
105 | // Creates the SVG for the NFT with the name
106 | string memory finalSvg = string(
107 | abi.encodePacked(svgPartOne, _name, svgPartTwo)
108 | );
109 | uint256 newRecordId = _tokenIds.current();
110 | uint256 length = StringUtils.strlen(name);
111 | string memory strLen = Strings.toString(length);
112 |
113 | console.log(
114 | "Registering %s.%s on the contract with tokenID %d",
115 | name,
116 | tld,
117 | newRecordId
118 | );
119 |
120 | // Creates the JSON metadata of our NFT. We do this by combining strings and encoding as base64
121 | string memory json = Base64.encode(
122 | bytes(
123 | string(
124 | abi.encodePacked(
125 | '{"name": "',
126 | _name,
127 | '", "description": "A domain on the Ninja name service", "image": "data:image/svg+xml;base64,',
128 | Base64.encode(bytes(finalSvg)),
129 | '","length":"',
130 | strLen,
131 | '"}'
132 | )
133 | )
134 | )
135 | );
136 |
137 | string memory finalTokenUri = string(
138 | abi.encodePacked("data:application/json;base64,", json)
139 | );
140 |
141 | console.log(
142 | "\n--------------------------------------------------------"
143 | );
144 | console.log("Final tokenURI", finalTokenUri);
145 | console.log(
146 | "--------------------------------------------------------\n"
147 | );
148 |
149 | _safeMint(msg.sender, newRecordId);
150 | _setTokenURI(newRecordId, finalTokenUri);
151 |
152 | domains[name] = msg.sender;
153 | names[newRecordId] = name;
154 |
155 | _tokenIds.increment();
156 | }
157 |
158 | /**
159 | * @notice - Returns the address registered for a specific domain name.
160 | * @param name - The domain's name.
161 | * @return - The address registered for that domain.
162 | */
163 | function getAddress(string calldata name) public view returns (address) {
164 | return domains[name];
165 | }
166 |
167 | /**
168 | * @notice - Sets a record for a specific domain name.
169 | * @param name - The domain's name.
170 | * @param record - The record to store.
171 | */
172 | function setRecord(string calldata name, string calldata record) public {
173 | require(
174 | domains[name] == msg.sender,
175 | "Only the owner of the domain can set a record"
176 | );
177 |
178 | records[name] = record;
179 | }
180 |
181 | /**
182 | * @notice - Provides the record stored for a specific domain name.
183 | * @param name - The domain's name.
184 | * @return - The record stored in that domain.
185 | */
186 | function getRecord(string calldata name)
187 | public
188 | view
189 | returns (string memory)
190 | {
191 | return records[name];
192 | }
193 |
194 | /**
195 | * @notice - Provides a list of all the domain names.
196 | * @return - The list of all the domain names.
197 | */
198 | function getAllNames() public view returns (string[] memory) {
199 | console.log("Getting all names from contract");
200 | string[] memory allNames = new string[](_tokenIds.current());
201 | for (uint256 i = 0; i < _tokenIds.current(); i++) {
202 | allNames[i] = names[i];
203 | console.log("Name for token %d is %s", i, allNames[i]);
204 | }
205 |
206 | return allNames;
207 | }
208 |
209 | /**
210 | * @dev - Requires the caller to be the contract's owner.
211 | */
212 | modifier onlyOwner() {
213 | require(msg.sender == owner);
214 | _;
215 | }
216 |
217 | /**
218 | * @notice - Withdraws the contract's balance, only valid for the owner.
219 | */
220 | function withdraw() public onlyOwner {
221 | uint256 amount = address(this).balance;
222 |
223 | (bool success, ) = msg.sender.call{value: amount}("");
224 | require(success, "Failed to withdraw Matic");
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/src/artifacts/contracts/Domains.sol/Domains.json:
--------------------------------------------------------------------------------
1 | {
2 | "_format": "hh-sol-artifact-1",
3 | "contractName": "Domains",
4 | "sourceName": "contracts/Domains.sol",
5 | "abi": [
6 | {
7 | "inputs": [
8 | {
9 | "internalType": "string",
10 | "name": "_tld",
11 | "type": "string"
12 | }
13 | ],
14 | "stateMutability": "payable",
15 | "type": "constructor"
16 | },
17 | {
18 | "anonymous": false,
19 | "inputs": [
20 | {
21 | "indexed": true,
22 | "internalType": "address",
23 | "name": "owner",
24 | "type": "address"
25 | },
26 | {
27 | "indexed": true,
28 | "internalType": "address",
29 | "name": "approved",
30 | "type": "address"
31 | },
32 | {
33 | "indexed": true,
34 | "internalType": "uint256",
35 | "name": "tokenId",
36 | "type": "uint256"
37 | }
38 | ],
39 | "name": "Approval",
40 | "type": "event"
41 | },
42 | {
43 | "anonymous": false,
44 | "inputs": [
45 | {
46 | "indexed": true,
47 | "internalType": "address",
48 | "name": "owner",
49 | "type": "address"
50 | },
51 | {
52 | "indexed": true,
53 | "internalType": "address",
54 | "name": "operator",
55 | "type": "address"
56 | },
57 | {
58 | "indexed": false,
59 | "internalType": "bool",
60 | "name": "approved",
61 | "type": "bool"
62 | }
63 | ],
64 | "name": "ApprovalForAll",
65 | "type": "event"
66 | },
67 | {
68 | "anonymous": false,
69 | "inputs": [
70 | {
71 | "indexed": true,
72 | "internalType": "address",
73 | "name": "from",
74 | "type": "address"
75 | },
76 | {
77 | "indexed": true,
78 | "internalType": "address",
79 | "name": "to",
80 | "type": "address"
81 | },
82 | {
83 | "indexed": true,
84 | "internalType": "uint256",
85 | "name": "tokenId",
86 | "type": "uint256"
87 | }
88 | ],
89 | "name": "Transfer",
90 | "type": "event"
91 | },
92 | {
93 | "inputs": [
94 | {
95 | "internalType": "address",
96 | "name": "to",
97 | "type": "address"
98 | },
99 | {
100 | "internalType": "uint256",
101 | "name": "tokenId",
102 | "type": "uint256"
103 | }
104 | ],
105 | "name": "approve",
106 | "outputs": [],
107 | "stateMutability": "nonpayable",
108 | "type": "function"
109 | },
110 | {
111 | "inputs": [
112 | {
113 | "internalType": "address",
114 | "name": "owner",
115 | "type": "address"
116 | }
117 | ],
118 | "name": "balanceOf",
119 | "outputs": [
120 | {
121 | "internalType": "uint256",
122 | "name": "",
123 | "type": "uint256"
124 | }
125 | ],
126 | "stateMutability": "view",
127 | "type": "function"
128 | },
129 | {
130 | "inputs": [
131 | {
132 | "internalType": "string",
133 | "name": "",
134 | "type": "string"
135 | }
136 | ],
137 | "name": "domains",
138 | "outputs": [
139 | {
140 | "internalType": "address",
141 | "name": "",
142 | "type": "address"
143 | }
144 | ],
145 | "stateMutability": "view",
146 | "type": "function"
147 | },
148 | {
149 | "inputs": [
150 | {
151 | "internalType": "string",
152 | "name": "name",
153 | "type": "string"
154 | }
155 | ],
156 | "name": "getAddress",
157 | "outputs": [
158 | {
159 | "internalType": "address",
160 | "name": "",
161 | "type": "address"
162 | }
163 | ],
164 | "stateMutability": "view",
165 | "type": "function"
166 | },
167 | {
168 | "inputs": [],
169 | "name": "getAllNames",
170 | "outputs": [
171 | {
172 | "internalType": "string[]",
173 | "name": "",
174 | "type": "string[]"
175 | }
176 | ],
177 | "stateMutability": "view",
178 | "type": "function"
179 | },
180 | {
181 | "inputs": [
182 | {
183 | "internalType": "uint256",
184 | "name": "tokenId",
185 | "type": "uint256"
186 | }
187 | ],
188 | "name": "getApproved",
189 | "outputs": [
190 | {
191 | "internalType": "address",
192 | "name": "",
193 | "type": "address"
194 | }
195 | ],
196 | "stateMutability": "view",
197 | "type": "function"
198 | },
199 | {
200 | "inputs": [
201 | {
202 | "internalType": "string",
203 | "name": "name",
204 | "type": "string"
205 | }
206 | ],
207 | "name": "getPrice",
208 | "outputs": [
209 | {
210 | "internalType": "uint256",
211 | "name": "",
212 | "type": "uint256"
213 | }
214 | ],
215 | "stateMutability": "pure",
216 | "type": "function"
217 | },
218 | {
219 | "inputs": [
220 | {
221 | "internalType": "string",
222 | "name": "name",
223 | "type": "string"
224 | }
225 | ],
226 | "name": "getRecord",
227 | "outputs": [
228 | {
229 | "internalType": "string",
230 | "name": "",
231 | "type": "string"
232 | }
233 | ],
234 | "stateMutability": "view",
235 | "type": "function"
236 | },
237 | {
238 | "inputs": [
239 | {
240 | "internalType": "address",
241 | "name": "owner",
242 | "type": "address"
243 | },
244 | {
245 | "internalType": "address",
246 | "name": "operator",
247 | "type": "address"
248 | }
249 | ],
250 | "name": "isApprovedForAll",
251 | "outputs": [
252 | {
253 | "internalType": "bool",
254 | "name": "",
255 | "type": "bool"
256 | }
257 | ],
258 | "stateMutability": "view",
259 | "type": "function"
260 | },
261 | {
262 | "inputs": [],
263 | "name": "name",
264 | "outputs": [
265 | {
266 | "internalType": "string",
267 | "name": "",
268 | "type": "string"
269 | }
270 | ],
271 | "stateMutability": "view",
272 | "type": "function"
273 | },
274 | {
275 | "inputs": [
276 | {
277 | "internalType": "uint256",
278 | "name": "",
279 | "type": "uint256"
280 | }
281 | ],
282 | "name": "names",
283 | "outputs": [
284 | {
285 | "internalType": "string",
286 | "name": "",
287 | "type": "string"
288 | }
289 | ],
290 | "stateMutability": "view",
291 | "type": "function"
292 | },
293 | {
294 | "inputs": [],
295 | "name": "owner",
296 | "outputs": [
297 | {
298 | "internalType": "address",
299 | "name": "",
300 | "type": "address"
301 | }
302 | ],
303 | "stateMutability": "view",
304 | "type": "function"
305 | },
306 | {
307 | "inputs": [
308 | {
309 | "internalType": "uint256",
310 | "name": "tokenId",
311 | "type": "uint256"
312 | }
313 | ],
314 | "name": "ownerOf",
315 | "outputs": [
316 | {
317 | "internalType": "address",
318 | "name": "",
319 | "type": "address"
320 | }
321 | ],
322 | "stateMutability": "view",
323 | "type": "function"
324 | },
325 | {
326 | "inputs": [
327 | {
328 | "internalType": "string",
329 | "name": "",
330 | "type": "string"
331 | }
332 | ],
333 | "name": "records",
334 | "outputs": [
335 | {
336 | "internalType": "string",
337 | "name": "",
338 | "type": "string"
339 | }
340 | ],
341 | "stateMutability": "view",
342 | "type": "function"
343 | },
344 | {
345 | "inputs": [
346 | {
347 | "internalType": "string",
348 | "name": "name",
349 | "type": "string"
350 | }
351 | ],
352 | "name": "register",
353 | "outputs": [],
354 | "stateMutability": "payable",
355 | "type": "function"
356 | },
357 | {
358 | "inputs": [
359 | {
360 | "internalType": "address",
361 | "name": "from",
362 | "type": "address"
363 | },
364 | {
365 | "internalType": "address",
366 | "name": "to",
367 | "type": "address"
368 | },
369 | {
370 | "internalType": "uint256",
371 | "name": "tokenId",
372 | "type": "uint256"
373 | }
374 | ],
375 | "name": "safeTransferFrom",
376 | "outputs": [],
377 | "stateMutability": "nonpayable",
378 | "type": "function"
379 | },
380 | {
381 | "inputs": [
382 | {
383 | "internalType": "address",
384 | "name": "from",
385 | "type": "address"
386 | },
387 | {
388 | "internalType": "address",
389 | "name": "to",
390 | "type": "address"
391 | },
392 | {
393 | "internalType": "uint256",
394 | "name": "tokenId",
395 | "type": "uint256"
396 | },
397 | {
398 | "internalType": "bytes",
399 | "name": "_data",
400 | "type": "bytes"
401 | }
402 | ],
403 | "name": "safeTransferFrom",
404 | "outputs": [],
405 | "stateMutability": "nonpayable",
406 | "type": "function"
407 | },
408 | {
409 | "inputs": [
410 | {
411 | "internalType": "address",
412 | "name": "operator",
413 | "type": "address"
414 | },
415 | {
416 | "internalType": "bool",
417 | "name": "approved",
418 | "type": "bool"
419 | }
420 | ],
421 | "name": "setApprovalForAll",
422 | "outputs": [],
423 | "stateMutability": "nonpayable",
424 | "type": "function"
425 | },
426 | {
427 | "inputs": [
428 | {
429 | "internalType": "string",
430 | "name": "name",
431 | "type": "string"
432 | },
433 | {
434 | "internalType": "string",
435 | "name": "record",
436 | "type": "string"
437 | }
438 | ],
439 | "name": "setRecord",
440 | "outputs": [],
441 | "stateMutability": "nonpayable",
442 | "type": "function"
443 | },
444 | {
445 | "inputs": [
446 | {
447 | "internalType": "bytes4",
448 | "name": "interfaceId",
449 | "type": "bytes4"
450 | }
451 | ],
452 | "name": "supportsInterface",
453 | "outputs": [
454 | {
455 | "internalType": "bool",
456 | "name": "",
457 | "type": "bool"
458 | }
459 | ],
460 | "stateMutability": "view",
461 | "type": "function"
462 | },
463 | {
464 | "inputs": [],
465 | "name": "symbol",
466 | "outputs": [
467 | {
468 | "internalType": "string",
469 | "name": "",
470 | "type": "string"
471 | }
472 | ],
473 | "stateMutability": "view",
474 | "type": "function"
475 | },
476 | {
477 | "inputs": [],
478 | "name": "tld",
479 | "outputs": [
480 | {
481 | "internalType": "string",
482 | "name": "",
483 | "type": "string"
484 | }
485 | ],
486 | "stateMutability": "view",
487 | "type": "function"
488 | },
489 | {
490 | "inputs": [
491 | {
492 | "internalType": "uint256",
493 | "name": "tokenId",
494 | "type": "uint256"
495 | }
496 | ],
497 | "name": "tokenURI",
498 | "outputs": [
499 | {
500 | "internalType": "string",
501 | "name": "",
502 | "type": "string"
503 | }
504 | ],
505 | "stateMutability": "view",
506 | "type": "function"
507 | },
508 | {
509 | "inputs": [
510 | {
511 | "internalType": "address",
512 | "name": "from",
513 | "type": "address"
514 | },
515 | {
516 | "internalType": "address",
517 | "name": "to",
518 | "type": "address"
519 | },
520 | {
521 | "internalType": "uint256",
522 | "name": "tokenId",
523 | "type": "uint256"
524 | }
525 | ],
526 | "name": "transferFrom",
527 | "outputs": [],
528 | "stateMutability": "nonpayable",
529 | "type": "function"
530 | },
531 | {
532 | "inputs": [],
533 | "name": "withdraw",
534 | "outputs": [],
535 | "stateMutability": "nonpayable",
536 | "type": "function"
537 | }
538 | ],
539 | "bytecode": "0x6080604052604051806107a0016040528061076c8152602001620053e861076c9139600a908051906020019062000038929190620002c8565b506040518060400160405280600d81526020017f3c2f746578743e3c2f7376673e00000000000000000000000000000000000000815250600b908051906020019062000086929190620002c8565b5060405162005b5438038062005b548339818101604052810190620000ac919062000515565b6040518060400160405280601481526020017f5a65642052756e204e616d6520536572766963650000000000000000000000008152506040518060400160405280600381526020017f5a4e530000000000000000000000000000000000000000000000000000000000815250816000908051906020019062000130929190620002c8565b50806001908051906020019062000149929190620002c8565b50505033600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060099080519060200190620001a5929190620002c8565b50620001f26040518060400160405280601881526020017f2573206e616d652073657276696365206465706c6f796564000000000000000081525082620001f960201b62001b211760201c565b5062000663565b6200029b828260405160240162000212929190620005c3565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506200029f60201b60201c565b5050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b828054620002d6906200062d565b90600052602060002090601f016020900481019282620002fa576000855562000346565b82601f106200031557805160ff191683800117855562000346565b8280016001018555821562000346579182015b828111156200034557825182559160200191906001019062000328565b5b50905062000355919062000359565b5090565b5b80821115620003745760008160009055506001016200035a565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620003e18262000396565b810181811067ffffffffffffffff82111715620004035762000402620003a7565b5b80604052505050565b60006200041862000378565b9050620004268282620003d6565b919050565b600067ffffffffffffffff821115620004495762000448620003a7565b5b620004548262000396565b9050602081019050919050565b60005b838110156200048157808201518184015260208101905062000464565b8381111562000491576000848401525b50505050565b6000620004ae620004a8846200042b565b6200040c565b905082815260208101848484011115620004cd57620004cc62000391565b5b620004da84828562000461565b509392505050565b600082601f830112620004fa57620004f96200038c565b5b81516200050c84826020860162000497565b91505092915050565b6000602082840312156200052e576200052d62000382565b5b600082015167ffffffffffffffff8111156200054f576200054e62000387565b5b6200055d84828501620004e2565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60006200058f8262000566565b6200059b818562000571565b9350620005ad81856020860162000461565b620005b88162000396565b840191505092915050565b60006040820190508181036000830152620005df818562000582565b90508181036020830152620005f5818462000582565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200064657607f821691505b602082108114156200065d576200065c620005fe565b5b50919050565b614d7580620006736000396000f3fe6080604052600436106101665760003560e01c8063541e771d116100d1578063b88d4fde1161008a578063c87b56dd11610064578063c87b56dd14610586578063e985e9c5146105c3578063f2c298be14610600578063fb825e5f1461061c57610166565b8063b88d4fde146104f7578063bf40fac114610520578063c1880a981461055d57610166565b8063541e771d146103c15780636352211e146103fe57806370a082311461043b5780638da5cb5b1461047857806395d89b41146104a3578063a22cb465146104ce57610166565b80632644923511610123578063264492351461029f5780632d551432146102dc5780633ccfd60b1461030757806342842e0e1461031e5780634622ab0314610347578063524f38891461038457610166565b806301ffc9a71461016b57806306fdde03146101a8578063081812fc146101d3578063095ea7b31461021057806311dd88451461023957806323b872dd14610276575b600080fd5b34801561017757600080fd5b50610192600480360381019061018d9190613006565b610647565b60405161019f919061304e565b60405180910390f35b3480156101b457600080fd5b506101bd610729565b6040516101ca9190613102565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f5919061315a565b6107bb565b60405161020791906131c8565b60405180910390f35b34801561021c57600080fd5b506102376004803603810190610232919061320f565b610840565b005b34801561024557600080fd5b50610260600480360381019061025b91906132b4565b610958565b60405161026d9190613102565b60405180910390f35b34801561028257600080fd5b5061029d60048036038101906102989190613301565b610a0b565b005b3480156102ab57600080fd5b506102c660048036038101906102c19190613484565b610a6b565b6040516102d391906131c8565b60405180910390f35b3480156102e857600080fd5b506102f1610ab4565b6040516102fe9190613102565b60405180910390f35b34801561031357600080fd5b5061031c610b42565b005b34801561032a57600080fd5b5061034560048036038101906103409190613301565b610c51565b005b34801561035357600080fd5b5061036e6004803603810190610369919061315a565b610c71565b60405161037b9190613102565b60405180910390f35b34801561039057600080fd5b506103ab60048036038101906103a691906132b4565b610d11565b6040516103b891906134dc565b60405180910390f35b3480156103cd57600080fd5b506103e860048036038101906103e39190613484565b610db7565b6040516103f59190613102565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061315a565b610e6d565b60405161043291906131c8565b60405180910390f35b34801561044757600080fd5b50610462600480360381019061045d91906134f7565b610f1f565b60405161046f91906134dc565b60405180910390f35b34801561048457600080fd5b5061048d610fd7565b60405161049a91906131c8565b60405180910390f35b3480156104af57600080fd5b506104b8610ffd565b6040516104c59190613102565b60405180910390f35b3480156104da57600080fd5b506104f560048036038101906104f09190613550565b61108f565b005b34801561050357600080fd5b5061051e60048036038101906105199190613631565b6110a5565b005b34801561052c57600080fd5b50610547600480360381019061054291906132b4565b611107565b60405161055491906131c8565b60405180910390f35b34801561056957600080fd5b50610584600480360381019061057f91906136b4565b611152565b005b34801561059257600080fd5b506105ad60048036038101906105a8919061315a565b611236565b6040516105ba9190613102565b60405180910390f35b3480156105cf57600080fd5b506105ea60048036038101906105e59190613735565b611388565b6040516105f7919061304e565b60405180910390f35b61061a600480360381019061061591906132b4565b61141c565b005b34801561062857600080fd5b50610631611943565b60405161063e9190613881565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061071257507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610722575061072182611bbd565b5b9050919050565b606060008054610738906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054610764906138d2565b80156107b15780601f10610786576101008083540402835291602001916107b1565b820191906000526020600020905b81548152906001019060200180831161079457829003601f168201915b5050505050905090565b60006107c682611c27565b610805576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fc90613976565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061084b82610e6d565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156108bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b390613a08565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108db611c93565b73ffffffffffffffffffffffffffffffffffffffff16148061090a575061090981610904611c93565b611388565b5b610949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094090613a9a565b60405180910390fd5b6109538383611c9b565b505050565b6060600e838360405161096c929190613aea565b90815260200160405180910390208054610985906138d2565b80601f01602080910402602001604051908101604052809291908181526020018280546109b1906138d2565b80156109fe5780601f106109d3576101008083540402835291602001916109fe565b820191906000526020600020905b8154815290600101906020018083116109e157829003601f168201915b5050505050905092915050565b610a1c610a16611c93565b82611d54565b610a5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5290613b75565b60405180910390fd5b610a66838383611e32565b505050565b600c818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60098054610ac1906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054610aed906138d2565b8015610b3a5780601f10610b0f57610100808354040283529160200191610b3a565b820191906000526020600020905b815481529060010190602001808311610b1d57829003601f168201915b505050505081565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b9c57600080fd5b600047905060003373ffffffffffffffffffffffffffffffffffffffff1682604051610bc790613bc6565b60006040518083038185875af1925050503d8060008114610c04576040519150601f19603f3d011682016040523d82523d6000602084013e610c09565b606091505b5050905080610c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4490613c27565b60405180910390fd5b5050565b610c6c838383604051806020016040528060008152506110a5565b505050565b600d6020528060005260406000206000915090508054610c90906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054610cbc906138d2565b8015610d095780601f10610cde57610100808354040283529160200191610d09565b820191906000526020600020905b815481529060010190602001808311610cec57829003601f168201915b505050505081565b600080610d6184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612099565b905060008111610d7057600080fd5b6003811415610d8a576706f05b59d3b20000915050610db1565b6004811415610da457670429d069189e0000915050610db1565b67016345785d8a00009150505b92915050565b600e818051602081018201805184825260208301602085012081835280955050505050506000915090508054610dec906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054610e18906138d2565b8015610e655780601f10610e3a57610100808354040283529160200191610e65565b820191906000526020600020905b815481529060010190602001808311610e4857829003601f168201915b505050505081565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0d90613cb9565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8790613d4b565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606001805461100c906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054611038906138d2565b80156110855780601f1061105a57610100808354040283529160200191611085565b820191906000526020600020905b81548152906001019060200180831161106857829003601f168201915b5050505050905090565b6110a161109a611c93565b838361224e565b5050565b6110b66110b0611c93565b83611d54565b6110f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ec90613b75565b60405180910390fd5b611101848484846123bb565b50505050565b6000600c838360405161111b929190613aea565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600c858560405161117b929190613aea565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f790613ddd565b60405180910390fd5b8181600e8686604051611214929190613aea565b9081526020016040518091039020919061122f929190612e71565b5050505050565b606061124182611c27565b611280576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127790613e6f565b60405180910390fd5b60006006600084815260200190815260200160002080546112a0906138d2565b80601f01602080910402602001604051908101604052809291908181526020018280546112cc906138d2565b80156113195780601f106112ee57610100808354040283529160200191611319565b820191906000526020600020905b8154815290600101906020018083116112fc57829003601f168201915b50505050509050600061132a612417565b9050600081511415611340578192505050611383565b60008251111561137557808260405160200161135d929190613ec0565b60405160208183030381529060405292505050611383565b61137e8461242e565b925050505b919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8181600361146d83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612099565b101580156114c85750600a6114c583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612099565b11155b611507576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114fe90613f56565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600c8585604051611531929190613aea565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146115b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ad90613fc2565b60405180910390fd5b60006115c28585610d11565b905080341015611607576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115fe9061402e565b60405180910390fd5b60008585600960405160200161161f9392919061412e565b60405160208183030381529060405290506000600a82600b6040516020016116499392919061415f565b6040516020818303038152906040529050600061166660076124d5565b905060006116b789898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612099565b905060006116c4826124e3565b90506117b8604051806060016040528060318152602001614c96603191398b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060098054611734906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054611760906138d2565b80156117ad5780601f10611782576101008083540402835291602001916117ad565b820191906000526020600020905b81548152906001019060200180831161179057829003601f168201915b505050505086612644565b60006117ee866117c7876126e6565b846040516020016117da9392919061430c565b6040516020818303038152906040526126e6565b905060008160405160200161180391906143b5565b6040516020818303038152906040529050611835604051806060016040528060398152602001614c5d6039913961287e565b6118746040518060400160405280600e81526020017f46696e616c20746f6b656e55524900000000000000000000000000000000000081525082611b21565b611895604051806060016040528060398152602001614cc76039913961287e565b61189f3386612917565b6118a98582612935565b33600c8d8d6040516118bc929190613aea565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b8b600d6000888152602001908152602001600020919061192a929190612e71565b5061193560076129a9565b505050505050505050505050565b60606119836040518060400160405280601f81526020017f47657474696e6720616c6c206e616d65732066726f6d20636f6e74726163740081525061287e565b600061198f60076124d5565b67ffffffffffffffff8111156119a8576119a7613359565b5b6040519080825280602002602001820160405280156119db57816020015b60608152602001906001900390816119c65790505b50905060005b6119eb60076124d5565b811015611b1957600d60008281526020019081526020016000208054611a10906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054611a3c906138d2565b8015611a895780601f10611a5e57610100808354040283529160200191611a89565b820191906000526020600020905b815481529060010190602001808311611a6c57829003601f168201915b5050505050828281518110611aa157611aa06143d7565b5b6020026020010181905250611b066040518060400160405280601781526020017f4e616d6520666f7220746f6b656e20256420697320257300000000000000000081525082848481518110611af957611af86143d7565b5b60200260200101516129bf565b8080611b1190614435565b9150506119e1565b508091505090565b611bb98282604051602401611b3792919061447e565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a5e565b5050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611d0e83610e6d565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d5f82611c27565b611d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9590614527565b60405180910390fd5b6000611da983610e6d565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e1857508373ffffffffffffffffffffffffffffffffffffffff16611e00846107bb565b73ffffffffffffffffffffffffffffffffffffffff16145b80611e295750611e288185611388565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611e5282610e6d565b73ffffffffffffffffffffffffffffffffffffffff1614611ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9f906145b9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611f18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0f9061464b565b60405180910390fd5b611f23838383612a87565b611f2e600082611c9b565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7e919061466b565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611fd5919061469f565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612094838383612a8c565b505050565b60008060008084519050600092505b808210156122435760008583815181106120c5576120c46143d7565b5b602001015160f81c60f81b9050608060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610156121145760018361210d919061469f565b925061222f565b60e060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610156121565760028361214f919061469f565b925061222e565b60f060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101561219857600383612191919061469f565b925061222d565b60f8801b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610156121d9576004836121d2919061469f565b925061222c565b60fc60f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101561221b57600583612214919061469f565b925061222b565b600683612228919061469f565b92505b5b5b5b5b50828061223b90614435565b9350506120a8565b829350505050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156122bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b490614741565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123ae919061304e565b60405180910390a3505050565b6123c6848484611e32565b6123d284848484612a91565b612411576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612408906147d3565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b606061243982611c27565b612478576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246f90614865565b60405180910390fd5b6000612482612417565b905060008151116124a257604051806020016040528060008152506124cd565b806124ac846124e3565b6040516020016124bd929190613ec0565b6040516020818303038152906040525b915050919050565b600081600001549050919050565b6060600082141561252b576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061263f565b600082905060005b6000821461255d57808061254690614435565b915050600a8261255691906148b4565b9150612533565b60008167ffffffffffffffff81111561257957612578613359565b5b6040519080825280601f01601f1916602001820160405280156125ab5781602001600182028036833780820191505090505b5090505b60008514612638576001826125c4919061466b565b9150600a856125d391906148e5565b60306125df919061469f565b60f81b8183815181106125f5576125f46143d7565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561263191906148b4565b94506125af565b8093505050505b919050565b6126e08484848460405160240161265e9493929190614916565b6040516020818303038152906040527f9fd009f5000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a5e565b50505050565b6060600082519050600081141561270f5760405180602001604052806000815250915050612879565b60006003600283612720919061469f565b61272a91906148b4565b60046127369190614970565b90506000602082612747919061469f565b67ffffffffffffffff8111156127605761275f613359565b5b6040519080825280601f01601f1916602001820160405280156127925781602001600182028036833780820191505090505b5090506000604051806060016040528060408152602001614d00604091399050600181016020830160005b868110156128365760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b905080845260048401935050506127bd565b50600386066001811461285057600281146128605761286b565b613d3d60f01b600283035261286b565b603d60f81b60018303525b508484525050819450505050505b919050565b612914816040516024016128929190613102565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a5e565b50565b612931828260405180602001604052806000815250612c19565b5050565b61293e82611c27565b61297d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297490614a3c565b60405180910390fd5b806006600084815260200190815260200160002090805190602001906129a4929190612ef7565b505050565b6001816000016000828254019250508190555050565b612a598383836040516024016129d793929190614a5c565b6040516020818303038152906040527fa3f5c739000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a5e565b505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b505050565b505050565b6000612ab28473ffffffffffffffffffffffffffffffffffffffff16612c74565b15612c0c578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612adb611c93565b8786866040518563ffffffff1660e01b8152600401612afd9493929190614af6565b6020604051808303816000875af1925050508015612b3957506040513d601f19601f82011682018060405250810190612b369190614b57565b60015b612bbc573d8060008114612b69576040519150601f19603f3d011682016040523d82523d6000602084013e612b6e565b606091505b50600081511415612bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bab906147d3565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612c11565b600190505b949350505050565b612c238383612c97565b612c306000848484612a91565b612c6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c66906147d3565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612d07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cfe90614bd0565b60405180910390fd5b612d1081611c27565b15612d50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4790614c3c565b60405180910390fd5b612d5c60008383612a87565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612dac919061469f565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612e6d60008383612a8c565b5050565b828054612e7d906138d2565b90600052602060002090601f016020900481019282612e9f5760008555612ee6565b82601f10612eb857803560ff1916838001178555612ee6565b82800160010185558215612ee6579182015b82811115612ee5578235825591602001919060010190612eca565b5b509050612ef39190612f7d565b5090565b828054612f03906138d2565b90600052602060002090601f016020900481019282612f255760008555612f6c565b82601f10612f3e57805160ff1916838001178555612f6c565b82800160010185558215612f6c579182015b82811115612f6b578251825591602001919060010190612f50565b5b509050612f799190612f7d565b5090565b5b80821115612f96576000816000905550600101612f7e565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fe381612fae565b8114612fee57600080fd5b50565b60008135905061300081612fda565b92915050565b60006020828403121561301c5761301b612fa4565b5b600061302a84828501612ff1565b91505092915050565b60008115159050919050565b61304881613033565b82525050565b6000602082019050613063600083018461303f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156130a3578082015181840152602081019050613088565b838111156130b2576000848401525b50505050565b6000601f19601f8301169050919050565b60006130d482613069565b6130de8185613074565b93506130ee818560208601613085565b6130f7816130b8565b840191505092915050565b6000602082019050818103600083015261311c81846130c9565b905092915050565b6000819050919050565b61313781613124565b811461314257600080fd5b50565b6000813590506131548161312e565b92915050565b6000602082840312156131705761316f612fa4565b5b600061317e84828501613145565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131b282613187565b9050919050565b6131c2816131a7565b82525050565b60006020820190506131dd60008301846131b9565b92915050565b6131ec816131a7565b81146131f757600080fd5b50565b600081359050613209816131e3565b92915050565b6000806040838503121561322657613225612fa4565b5b6000613234858286016131fa565b925050602061324585828601613145565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f8401126132745761327361324f565b5b8235905067ffffffffffffffff81111561329157613290613254565b5b6020830191508360018202830111156132ad576132ac613259565b5b9250929050565b600080602083850312156132cb576132ca612fa4565b5b600083013567ffffffffffffffff8111156132e9576132e8612fa9565b5b6132f58582860161325e565b92509250509250929050565b60008060006060848603121561331a57613319612fa4565b5b6000613328868287016131fa565b9350506020613339868287016131fa565b925050604061334a86828701613145565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613391826130b8565b810181811067ffffffffffffffff821117156133b0576133af613359565b5b80604052505050565b60006133c3612f9a565b90506133cf8282613388565b919050565b600067ffffffffffffffff8211156133ef576133ee613359565b5b6133f8826130b8565b9050602081019050919050565b82818337600083830152505050565b6000613427613422846133d4565b6133b9565b90508281526020810184848401111561344357613442613354565b5b61344e848285613405565b509392505050565b600082601f83011261346b5761346a61324f565b5b813561347b848260208601613414565b91505092915050565b60006020828403121561349a57613499612fa4565b5b600082013567ffffffffffffffff8111156134b8576134b7612fa9565b5b6134c484828501613456565b91505092915050565b6134d681613124565b82525050565b60006020820190506134f160008301846134cd565b92915050565b60006020828403121561350d5761350c612fa4565b5b600061351b848285016131fa565b91505092915050565b61352d81613033565b811461353857600080fd5b50565b60008135905061354a81613524565b92915050565b6000806040838503121561356757613566612fa4565b5b6000613575858286016131fa565b92505060206135868582860161353b565b9150509250929050565b600067ffffffffffffffff8211156135ab576135aa613359565b5b6135b4826130b8565b9050602081019050919050565b60006135d46135cf84613590565b6133b9565b9050828152602081018484840111156135f0576135ef613354565b5b6135fb848285613405565b509392505050565b600082601f8301126136185761361761324f565b5b81356136288482602086016135c1565b91505092915050565b6000806000806080858703121561364b5761364a612fa4565b5b6000613659878288016131fa565b945050602061366a878288016131fa565b935050604061367b87828801613145565b925050606085013567ffffffffffffffff81111561369c5761369b612fa9565b5b6136a887828801613603565b91505092959194509250565b600080600080604085870312156136ce576136cd612fa4565b5b600085013567ffffffffffffffff8111156136ec576136eb612fa9565b5b6136f88782880161325e565b9450945050602085013567ffffffffffffffff81111561371b5761371a612fa9565b5b6137278782880161325e565b925092505092959194509250565b6000806040838503121561374c5761374b612fa4565b5b600061375a858286016131fa565b925050602061376b858286016131fa565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b60006137bd82613069565b6137c781856137a1565b93506137d7818560208601613085565b6137e0816130b8565b840191505092915050565b60006137f783836137b2565b905092915050565b6000602082019050919050565b600061381782613775565b6138218185613780565b93508360208202850161383385613791565b8060005b8581101561386f578484038952815161385085826137eb565b945061385b836137ff565b925060208a01995050600181019050613837565b50829750879550505050505092915050565b6000602082019050818103600083015261389b818461380c565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806138ea57607f821691505b602082108114156138fe576138fd6138a3565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b6000613960602c83613074565b915061396b82613904565b604082019050919050565b6000602082019050818103600083015261398f81613953565b9050919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006139f2602183613074565b91506139fd82613996565b604082019050919050565b60006020820190508181036000830152613a21816139e5565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b6000613a84603883613074565b9150613a8f82613a28565b604082019050919050565b60006020820190508181036000830152613ab381613a77565b9050919050565b600081905092915050565b6000613ad18385613aba565b9350613ade838584613405565b82840190509392505050565b6000613af7828486613ac5565b91508190509392505050565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b6000613b5f603183613074565b9150613b6a82613b03565b604082019050919050565b60006020820190508181036000830152613b8e81613b52565b9050919050565b600081905092915050565b50565b6000613bb0600083613b95565b9150613bbb82613ba0565b600082019050919050565b6000613bd182613ba3565b9150819050919050565b7f4661696c656420746f207769746864726177204d617469630000000000000000600082015250565b6000613c11601883613074565b9150613c1c82613bdb565b602082019050919050565b60006020820190508181036000830152613c4081613c04565b9050919050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b6000613ca3602983613074565b9150613cae82613c47565b604082019050919050565b60006020820190508181036000830152613cd281613c96565b9050919050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b6000613d35602a83613074565b9150613d4082613cd9565b604082019050919050565b60006020820190508181036000830152613d6481613d28565b9050919050565b7f4f6e6c7920746865206f776e6572206f662074686520646f6d61696e2063616e60008201527f207365742061207265636f726400000000000000000000000000000000000000602082015250565b6000613dc7602d83613074565b9150613dd282613d6b565b604082019050919050565b60006020820190508181036000830152613df681613dba565b9050919050565b7f45524337323155524953746f726167653a2055524920717565727920666f722060008201527f6e6f6e6578697374656e7420746f6b656e000000000000000000000000000000602082015250565b6000613e59603183613074565b9150613e6482613dfd565b604082019050919050565b60006020820190508181036000830152613e8881613e4c565b9050919050565b6000613e9a82613069565b613ea48185613aba565b9350613eb4818560208601613085565b80840191505092915050565b6000613ecc8285613e8f565b9150613ed88284613e8f565b91508190509392505050565b7f4e616d65732063616e2068617665206265747765656e203320616e642031302060008201527f6368617273000000000000000000000000000000000000000000000000000000602082015250565b6000613f40602583613074565b9150613f4b82613ee4565b604082019050919050565b60006020820190508181036000830152613f6f81613f33565b9050919050565b7f4e616d6520697320616c726561647920696e2075736500000000000000000000600082015250565b6000613fac601683613074565b9150613fb782613f76565b602082019050919050565b60006020820190508181036000830152613fdb81613f9f565b9050919050565b7f4e6f7420656e6f756768204d4154494320706169640000000000000000000000600082015250565b6000614018601583613074565b915061402382613fe2565b602082019050919050565b600060208201905081810360008301526140478161400b565b9050919050565b7f2e00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614084600183613aba565b915061408f8261404e565b600182019050919050565b60008190508160005260206000209050919050565b600081546140bc816138d2565b6140c68186613aba565b945060018216600081146140e157600181146140f257614125565b60ff19831686528186019350614125565b6140fb8561409a565b60005b8381101561411d578154818901526001820191506020810190506140fe565b838801955050505b50505092915050565b600061413b828587613ac5565b915061414682614077565b915061415282846140af565b9150819050949350505050565b600061416b82866140af565b91506141778285613e8f565b915061418382846140af565b9150819050949350505050565b7f7b226e616d65223a202200000000000000000000000000000000000000000000600082015250565b60006141c6600a83613aba565b91506141d182614190565b600a82019050919050565b7f222c20226465736372697074696f6e223a20224120646f6d61696e206f6e207460008201527f6865204e696e6a61206e616d652073657276696365222c2022696d616765223a60208201527f2022646174613a696d6167652f7376672b786d6c3b6261736536342c00000000604082015250565b600061425e605c83613aba565b9150614269826141dc565b605c82019050919050565b7f222c226c656e677468223a220000000000000000000000000000000000000000600082015250565b60006142aa600c83613aba565b91506142b582614274565b600c82019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b60006142f6600283613aba565b9150614301826142c0565b600282019050919050565b6000614317826141b9565b91506143238286613e8f565b915061432e82614251565b915061433a8285613e8f565b91506143458261429d565b91506143518284613e8f565b915061435c826142e9565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b600061439f601d83613aba565b91506143aa82614369565b601d82019050919050565b60006143c082614392565b91506143cc8284613e8f565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061444082613124565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561447357614472614406565b5b600182019050919050565b6000604082019050818103600083015261449881856130c9565b905081810360208301526144ac81846130c9565b90509392505050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b6000614511602c83613074565b915061451c826144b5565b604082019050919050565b6000602082019050818103600083015261454081614504565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006145a3602583613074565b91506145ae82614547565b604082019050919050565b600060208201905081810360008301526145d281614596565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614635602483613074565b9150614640826145d9565b604082019050919050565b6000602082019050818103600083015261466481614628565b9050919050565b600061467682613124565b915061468183613124565b92508282101561469457614693614406565b5b828203905092915050565b60006146aa82613124565b91506146b583613124565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156146ea576146e9614406565b5b828201905092915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061472b601983613074565b9150614736826146f5565b602082019050919050565b6000602082019050818103600083015261475a8161471e565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006147bd603283613074565b91506147c882614761565b604082019050919050565b600060208201905081810360008301526147ec816147b0565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b600061484f602f83613074565b915061485a826147f3565b604082019050919050565b6000602082019050818103600083015261487e81614842565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006148bf82613124565b91506148ca83613124565b9250826148da576148d9614885565b5b828204905092915050565b60006148f082613124565b91506148fb83613124565b92508261490b5761490a614885565b5b828206905092915050565b6000608082019050818103600083015261493081876130c9565b9050818103602083015261494481866130c9565b9050818103604083015261495881856130c9565b905061496760608301846134cd565b95945050505050565b600061497b82613124565b915061498683613124565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156149bf576149be614406565b5b828202905092915050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000614a26602e83613074565b9150614a31826149ca565b604082019050919050565b60006020820190508181036000830152614a5581614a19565b9050919050565b60006060820190508181036000830152614a7681866130c9565b9050614a8560208301856134cd565b8181036040830152614a9781846130c9565b9050949350505050565b600081519050919050565b600082825260208201905092915050565b6000614ac882614aa1565b614ad28185614aac565b9350614ae2818560208601613085565b614aeb816130b8565b840191505092915050565b6000608082019050614b0b60008301876131b9565b614b1860208301866131b9565b614b2560408301856134cd565b8181036060830152614b378184614abd565b905095945050505050565b600081519050614b5181612fda565b92915050565b600060208284031215614b6d57614b6c612fa4565b5b6000614b7b84828501614b42565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614bba602083613074565b9150614bc582614b84565b602082019050919050565b60006020820190508181036000830152614be981614bad565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614c26601c83613074565b9150614c3182614bf0565b602082019050919050565b60006020820190508181036000830152614c5581614c19565b905091905056fe0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d5265676973746572696e672025732e2573206f6e2074686520636f6e7472616374207769746820746f6b656e49442025642d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0a4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220f34ae7380f9822c278ead0324dee89e34ba7d535e8d05183ad425e34b68f48ba64736f6c634300080a00333c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222077696474683d2232373022206865696768743d22323730222066696c6c3d226e6f6e65223e3c706174682066696c6c3d2275726c282361292220643d224d302030683237307632373048307a222f3e3c646566733e3c66696c7465722069643d22622220636f6c6f722d696e746572706f6c6174696f6e2d66696c746572733d2273524742222066696c746572556e6974733d227573657253706163654f6e55736522206865696768743d22323730222077696474683d22323730223e3c666544726f70536861646f772064783d2230222064793d22312220737464446576696174696f6e3d22322220666c6f6f642d6f7061636974793d222e323235222077696474683d223230302522206865696768743d2232303025222f3e3c2f66696c7465723e3c2f646566733e3c7061746820643d224d37322e3836332034322e39343961342e33383220342e3338322030203020302d342e33393420306c2d31302e30383120362e3033322d362e383520332e3933342d31302e30383120362e30333261342e33383220342e3338322030203020312d342e33393420306c2d382e3031332d342e37323161342e353220342e35322030203020312d312e3538392d312e36313620342e353420342e35342030203020312d2e3630382d322e313837762d392e333161342e323720342e3237203020302031202e3537322d322e32303820342e323520342e323520302030203120312e3632352d312e3539356c372e3838342d342e353961342e33383220342e33383220302030203120342e33393420306c372e38383420342e353961342e353220342e353220302030203120312e35383920312e36313620342e353420342e3534203020302031202e36303820322e31383776362e3033326c362e38352d342e303635762d362e30333261342e323720342e32372030203020302d2e3537322d322e32303820342e323520342e32352030203020302d312e3632352d312e3539354c34312e3435362032342e353961342e33383220342e3338322030203020302d342e33393420306c2d31342e38363420382e36353561342e323520342e32352030203020302d312e36323520312e35393520342e32373320342e3237332030203020302d2e35373220322e3230387631372e34343161342e323720342e3237203020302030202e35373220322e32303820342e323520342e323520302030203020312e36323520312e3539356c31342e38363420382e36353561342e33383220342e33383220302030203020342e33393420306c31302e3038312d352e39303120362e38352d342e3036352031302e3038312d352e39303161342e33383220342e33383220302030203120342e33393420306c372e38383420342e353961342e353220342e353220302030203120312e35383920312e36313620342e353420342e3534203020302031202e36303820322e31383776392e33313161342e323720342e32372030203020312d2e35373220322e32303820342e323520342e32352030203020312d312e36323520312e3539356c2d372e38383420342e37323161342e33383220342e3338322030203020312d342e33393420306c2d372e3838342d342e353961342e353220342e35322030203020312d312e3538392d312e36313620342e353320342e35332030203020312d2e3630382d322e313837762d362e3033326c2d362e383520342e30363576362e30333261342e323720342e3237203020302030202e35373220322e32303820342e323520342e323520302030203020312e36323520312e3539356c31342e38363420382e36353561342e33383220342e33383220302030203020342e33393420306c31342e3836342d382e36353561342e35343520342e35343520302030203020322e3139382d332e3830335635352e35333861342e323720342e32372030203020302d2e3537322d322e32303820342e323520342e32352030203020302d312e3632352d312e3539356c2d31342e3939332d382e3738367a222066696c6c3d2223666666222f3e3c646566733e3c6c696e6561724772616469656e742069643d2261222078313d2230222079313d2230222078323d22323730222079323d2232373022206772616469656e74556e6974733d227573657253706163654f6e557365223e3c73746f702073746f702d636f6c6f723d2276696f6c6574222f3e3c73746f70206f66667365743d2231222073746f702d6f7061636974793d222e3939222f3e3c2f6c696e6561724772616469656e743e3c2f646566733e3c7465787420783d223530252220793d223233312220746578742d616e63686f723d226d6964646c652220666f6e742d73697a653d223237222066696c6c3d2223666666222066696c7465723d2275726c282362292220666f6e742d66616d696c793d22506c7573204a616b617274612053616e732c44656a6156752053616e732c4e6f746f20436f6c6f7220456d6f6a692c4170706c6520436f6c6f7220456d6f6a692c73616e732d73657269662220666f6e742d7765696768743d22626f6c64223e",
540 | "deployedBytecode": "0x6080604052600436106101665760003560e01c8063541e771d116100d1578063b88d4fde1161008a578063c87b56dd11610064578063c87b56dd14610586578063e985e9c5146105c3578063f2c298be14610600578063fb825e5f1461061c57610166565b8063b88d4fde146104f7578063bf40fac114610520578063c1880a981461055d57610166565b8063541e771d146103c15780636352211e146103fe57806370a082311461043b5780638da5cb5b1461047857806395d89b41146104a3578063a22cb465146104ce57610166565b80632644923511610123578063264492351461029f5780632d551432146102dc5780633ccfd60b1461030757806342842e0e1461031e5780634622ab0314610347578063524f38891461038457610166565b806301ffc9a71461016b57806306fdde03146101a8578063081812fc146101d3578063095ea7b31461021057806311dd88451461023957806323b872dd14610276575b600080fd5b34801561017757600080fd5b50610192600480360381019061018d9190613006565b610647565b60405161019f919061304e565b60405180910390f35b3480156101b457600080fd5b506101bd610729565b6040516101ca9190613102565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f5919061315a565b6107bb565b60405161020791906131c8565b60405180910390f35b34801561021c57600080fd5b506102376004803603810190610232919061320f565b610840565b005b34801561024557600080fd5b50610260600480360381019061025b91906132b4565b610958565b60405161026d9190613102565b60405180910390f35b34801561028257600080fd5b5061029d60048036038101906102989190613301565b610a0b565b005b3480156102ab57600080fd5b506102c660048036038101906102c19190613484565b610a6b565b6040516102d391906131c8565b60405180910390f35b3480156102e857600080fd5b506102f1610ab4565b6040516102fe9190613102565b60405180910390f35b34801561031357600080fd5b5061031c610b42565b005b34801561032a57600080fd5b5061034560048036038101906103409190613301565b610c51565b005b34801561035357600080fd5b5061036e6004803603810190610369919061315a565b610c71565b60405161037b9190613102565b60405180910390f35b34801561039057600080fd5b506103ab60048036038101906103a691906132b4565b610d11565b6040516103b891906134dc565b60405180910390f35b3480156103cd57600080fd5b506103e860048036038101906103e39190613484565b610db7565b6040516103f59190613102565b60405180910390f35b34801561040a57600080fd5b506104256004803603810190610420919061315a565b610e6d565b60405161043291906131c8565b60405180910390f35b34801561044757600080fd5b50610462600480360381019061045d91906134f7565b610f1f565b60405161046f91906134dc565b60405180910390f35b34801561048457600080fd5b5061048d610fd7565b60405161049a91906131c8565b60405180910390f35b3480156104af57600080fd5b506104b8610ffd565b6040516104c59190613102565b60405180910390f35b3480156104da57600080fd5b506104f560048036038101906104f09190613550565b61108f565b005b34801561050357600080fd5b5061051e60048036038101906105199190613631565b6110a5565b005b34801561052c57600080fd5b50610547600480360381019061054291906132b4565b611107565b60405161055491906131c8565b60405180910390f35b34801561056957600080fd5b50610584600480360381019061057f91906136b4565b611152565b005b34801561059257600080fd5b506105ad60048036038101906105a8919061315a565b611236565b6040516105ba9190613102565b60405180910390f35b3480156105cf57600080fd5b506105ea60048036038101906105e59190613735565b611388565b6040516105f7919061304e565b60405180910390f35b61061a600480360381019061061591906132b4565b61141c565b005b34801561062857600080fd5b50610631611943565b60405161063e9190613881565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061071257507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610722575061072182611bbd565b5b9050919050565b606060008054610738906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054610764906138d2565b80156107b15780601f10610786576101008083540402835291602001916107b1565b820191906000526020600020905b81548152906001019060200180831161079457829003601f168201915b5050505050905090565b60006107c682611c27565b610805576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fc90613976565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061084b82610e6d565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156108bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b390613a08565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108db611c93565b73ffffffffffffffffffffffffffffffffffffffff16148061090a575061090981610904611c93565b611388565b5b610949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094090613a9a565b60405180910390fd5b6109538383611c9b565b505050565b6060600e838360405161096c929190613aea565b90815260200160405180910390208054610985906138d2565b80601f01602080910402602001604051908101604052809291908181526020018280546109b1906138d2565b80156109fe5780601f106109d3576101008083540402835291602001916109fe565b820191906000526020600020905b8154815290600101906020018083116109e157829003601f168201915b5050505050905092915050565b610a1c610a16611c93565b82611d54565b610a5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5290613b75565b60405180910390fd5b610a66838383611e32565b505050565b600c818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60098054610ac1906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054610aed906138d2565b8015610b3a5780601f10610b0f57610100808354040283529160200191610b3a565b820191906000526020600020905b815481529060010190602001808311610b1d57829003601f168201915b505050505081565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b9c57600080fd5b600047905060003373ffffffffffffffffffffffffffffffffffffffff1682604051610bc790613bc6565b60006040518083038185875af1925050503d8060008114610c04576040519150601f19603f3d011682016040523d82523d6000602084013e610c09565b606091505b5050905080610c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4490613c27565b60405180910390fd5b5050565b610c6c838383604051806020016040528060008152506110a5565b505050565b600d6020528060005260406000206000915090508054610c90906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054610cbc906138d2565b8015610d095780601f10610cde57610100808354040283529160200191610d09565b820191906000526020600020905b815481529060010190602001808311610cec57829003601f168201915b505050505081565b600080610d6184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612099565b905060008111610d7057600080fd5b6003811415610d8a576706f05b59d3b20000915050610db1565b6004811415610da457670429d069189e0000915050610db1565b67016345785d8a00009150505b92915050565b600e818051602081018201805184825260208301602085012081835280955050505050506000915090508054610dec906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054610e18906138d2565b8015610e655780601f10610e3a57610100808354040283529160200191610e65565b820191906000526020600020905b815481529060010190602001808311610e4857829003601f168201915b505050505081565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0d90613cb9565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8790613d4b565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606001805461100c906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054611038906138d2565b80156110855780601f1061105a57610100808354040283529160200191611085565b820191906000526020600020905b81548152906001019060200180831161106857829003601f168201915b5050505050905090565b6110a161109a611c93565b838361224e565b5050565b6110b66110b0611c93565b83611d54565b6110f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ec90613b75565b60405180910390fd5b611101848484846123bb565b50505050565b6000600c838360405161111b929190613aea565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600c858560405161117b929190613aea565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f790613ddd565b60405180910390fd5b8181600e8686604051611214929190613aea565b9081526020016040518091039020919061122f929190612e71565b5050505050565b606061124182611c27565b611280576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127790613e6f565b60405180910390fd5b60006006600084815260200190815260200160002080546112a0906138d2565b80601f01602080910402602001604051908101604052809291908181526020018280546112cc906138d2565b80156113195780601f106112ee57610100808354040283529160200191611319565b820191906000526020600020905b8154815290600101906020018083116112fc57829003601f168201915b50505050509050600061132a612417565b9050600081511415611340578192505050611383565b60008251111561137557808260405160200161135d929190613ec0565b60405160208183030381529060405292505050611383565b61137e8461242e565b925050505b919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8181600361146d83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612099565b101580156114c85750600a6114c583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612099565b11155b611507576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114fe90613f56565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600c8585604051611531929190613aea565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146115b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ad90613fc2565b60405180910390fd5b60006115c28585610d11565b905080341015611607576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115fe9061402e565b60405180910390fd5b60008585600960405160200161161f9392919061412e565b60405160208183030381529060405290506000600a82600b6040516020016116499392919061415f565b6040516020818303038152906040529050600061166660076124d5565b905060006116b789898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612099565b905060006116c4826124e3565b90506117b8604051806060016040528060318152602001614c96603191398b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060098054611734906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054611760906138d2565b80156117ad5780601f10611782576101008083540402835291602001916117ad565b820191906000526020600020905b81548152906001019060200180831161179057829003601f168201915b505050505086612644565b60006117ee866117c7876126e6565b846040516020016117da9392919061430c565b6040516020818303038152906040526126e6565b905060008160405160200161180391906143b5565b6040516020818303038152906040529050611835604051806060016040528060398152602001614c5d6039913961287e565b6118746040518060400160405280600e81526020017f46696e616c20746f6b656e55524900000000000000000000000000000000000081525082611b21565b611895604051806060016040528060398152602001614cc76039913961287e565b61189f3386612917565b6118a98582612935565b33600c8d8d6040516118bc929190613aea565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b8b600d6000888152602001908152602001600020919061192a929190612e71565b5061193560076129a9565b505050505050505050505050565b60606119836040518060400160405280601f81526020017f47657474696e6720616c6c206e616d65732066726f6d20636f6e74726163740081525061287e565b600061198f60076124d5565b67ffffffffffffffff8111156119a8576119a7613359565b5b6040519080825280602002602001820160405280156119db57816020015b60608152602001906001900390816119c65790505b50905060005b6119eb60076124d5565b811015611b1957600d60008281526020019081526020016000208054611a10906138d2565b80601f0160208091040260200160405190810160405280929190818152602001828054611a3c906138d2565b8015611a895780601f10611a5e57610100808354040283529160200191611a89565b820191906000526020600020905b815481529060010190602001808311611a6c57829003601f168201915b5050505050828281518110611aa157611aa06143d7565b5b6020026020010181905250611b066040518060400160405280601781526020017f4e616d6520666f7220746f6b656e20256420697320257300000000000000000081525082848481518110611af957611af86143d7565b5b60200260200101516129bf565b8080611b1190614435565b9150506119e1565b508091505090565b611bb98282604051602401611b3792919061447e565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a5e565b5050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611d0e83610e6d565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d5f82611c27565b611d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9590614527565b60405180910390fd5b6000611da983610e6d565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e1857508373ffffffffffffffffffffffffffffffffffffffff16611e00846107bb565b73ffffffffffffffffffffffffffffffffffffffff16145b80611e295750611e288185611388565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611e5282610e6d565b73ffffffffffffffffffffffffffffffffffffffff1614611ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9f906145b9565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611f18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0f9061464b565b60405180910390fd5b611f23838383612a87565b611f2e600082611c9b565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7e919061466b565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611fd5919061469f565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612094838383612a8c565b505050565b60008060008084519050600092505b808210156122435760008583815181106120c5576120c46143d7565b5b602001015160f81c60f81b9050608060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610156121145760018361210d919061469f565b925061222f565b60e060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610156121565760028361214f919061469f565b925061222e565b60f060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101561219857600383612191919061469f565b925061222d565b60f8801b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610156121d9576004836121d2919061469f565b925061222c565b60fc60f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101561221b57600583612214919061469f565b925061222b565b600683612228919061469f565b92505b5b5b5b5b50828061223b90614435565b9350506120a8565b829350505050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156122bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b490614741565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123ae919061304e565b60405180910390a3505050565b6123c6848484611e32565b6123d284848484612a91565b612411576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612408906147d3565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b606061243982611c27565b612478576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246f90614865565b60405180910390fd5b6000612482612417565b905060008151116124a257604051806020016040528060008152506124cd565b806124ac846124e3565b6040516020016124bd929190613ec0565b6040516020818303038152906040525b915050919050565b600081600001549050919050565b6060600082141561252b576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061263f565b600082905060005b6000821461255d57808061254690614435565b915050600a8261255691906148b4565b9150612533565b60008167ffffffffffffffff81111561257957612578613359565b5b6040519080825280601f01601f1916602001820160405280156125ab5781602001600182028036833780820191505090505b5090505b60008514612638576001826125c4919061466b565b9150600a856125d391906148e5565b60306125df919061469f565b60f81b8183815181106125f5576125f46143d7565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561263191906148b4565b94506125af565b8093505050505b919050565b6126e08484848460405160240161265e9493929190614916565b6040516020818303038152906040527f9fd009f5000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a5e565b50505050565b6060600082519050600081141561270f5760405180602001604052806000815250915050612879565b60006003600283612720919061469f565b61272a91906148b4565b60046127369190614970565b90506000602082612747919061469f565b67ffffffffffffffff8111156127605761275f613359565b5b6040519080825280601f01601f1916602001820160405280156127925781602001600182028036833780820191505090505b5090506000604051806060016040528060408152602001614d00604091399050600181016020830160005b868110156128365760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b905080845260048401935050506127bd565b50600386066001811461285057600281146128605761286b565b613d3d60f01b600283035261286b565b603d60f81b60018303525b508484525050819450505050505b919050565b612914816040516024016128929190613102565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a5e565b50565b612931828260405180602001604052806000815250612c19565b5050565b61293e82611c27565b61297d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297490614a3c565b60405180910390fd5b806006600084815260200190815260200160002090805190602001906129a4929190612ef7565b505050565b6001816000016000828254019250508190555050565b612a598383836040516024016129d793929190614a5c565b6040516020818303038152906040527fa3f5c739000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a5e565b505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b505050565b505050565b6000612ab28473ffffffffffffffffffffffffffffffffffffffff16612c74565b15612c0c578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612adb611c93565b8786866040518563ffffffff1660e01b8152600401612afd9493929190614af6565b6020604051808303816000875af1925050508015612b3957506040513d601f19601f82011682018060405250810190612b369190614b57565b60015b612bbc573d8060008114612b69576040519150601f19603f3d011682016040523d82523d6000602084013e612b6e565b606091505b50600081511415612bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bab906147d3565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612c11565b600190505b949350505050565b612c238383612c97565b612c306000848484612a91565b612c6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c66906147d3565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612d07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cfe90614bd0565b60405180910390fd5b612d1081611c27565b15612d50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4790614c3c565b60405180910390fd5b612d5c60008383612a87565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612dac919061469f565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612e6d60008383612a8c565b5050565b828054612e7d906138d2565b90600052602060002090601f016020900481019282612e9f5760008555612ee6565b82601f10612eb857803560ff1916838001178555612ee6565b82800160010185558215612ee6579182015b82811115612ee5578235825591602001919060010190612eca565b5b509050612ef39190612f7d565b5090565b828054612f03906138d2565b90600052602060002090601f016020900481019282612f255760008555612f6c565b82601f10612f3e57805160ff1916838001178555612f6c565b82800160010185558215612f6c579182015b82811115612f6b578251825591602001919060010190612f50565b5b509050612f799190612f7d565b5090565b5b80821115612f96576000816000905550600101612f7e565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fe381612fae565b8114612fee57600080fd5b50565b60008135905061300081612fda565b92915050565b60006020828403121561301c5761301b612fa4565b5b600061302a84828501612ff1565b91505092915050565b60008115159050919050565b61304881613033565b82525050565b6000602082019050613063600083018461303f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156130a3578082015181840152602081019050613088565b838111156130b2576000848401525b50505050565b6000601f19601f8301169050919050565b60006130d482613069565b6130de8185613074565b93506130ee818560208601613085565b6130f7816130b8565b840191505092915050565b6000602082019050818103600083015261311c81846130c9565b905092915050565b6000819050919050565b61313781613124565b811461314257600080fd5b50565b6000813590506131548161312e565b92915050565b6000602082840312156131705761316f612fa4565b5b600061317e84828501613145565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131b282613187565b9050919050565b6131c2816131a7565b82525050565b60006020820190506131dd60008301846131b9565b92915050565b6131ec816131a7565b81146131f757600080fd5b50565b600081359050613209816131e3565b92915050565b6000806040838503121561322657613225612fa4565b5b6000613234858286016131fa565b925050602061324585828601613145565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f8401126132745761327361324f565b5b8235905067ffffffffffffffff81111561329157613290613254565b5b6020830191508360018202830111156132ad576132ac613259565b5b9250929050565b600080602083850312156132cb576132ca612fa4565b5b600083013567ffffffffffffffff8111156132e9576132e8612fa9565b5b6132f58582860161325e565b92509250509250929050565b60008060006060848603121561331a57613319612fa4565b5b6000613328868287016131fa565b9350506020613339868287016131fa565b925050604061334a86828701613145565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613391826130b8565b810181811067ffffffffffffffff821117156133b0576133af613359565b5b80604052505050565b60006133c3612f9a565b90506133cf8282613388565b919050565b600067ffffffffffffffff8211156133ef576133ee613359565b5b6133f8826130b8565b9050602081019050919050565b82818337600083830152505050565b6000613427613422846133d4565b6133b9565b90508281526020810184848401111561344357613442613354565b5b61344e848285613405565b509392505050565b600082601f83011261346b5761346a61324f565b5b813561347b848260208601613414565b91505092915050565b60006020828403121561349a57613499612fa4565b5b600082013567ffffffffffffffff8111156134b8576134b7612fa9565b5b6134c484828501613456565b91505092915050565b6134d681613124565b82525050565b60006020820190506134f160008301846134cd565b92915050565b60006020828403121561350d5761350c612fa4565b5b600061351b848285016131fa565b91505092915050565b61352d81613033565b811461353857600080fd5b50565b60008135905061354a81613524565b92915050565b6000806040838503121561356757613566612fa4565b5b6000613575858286016131fa565b92505060206135868582860161353b565b9150509250929050565b600067ffffffffffffffff8211156135ab576135aa613359565b5b6135b4826130b8565b9050602081019050919050565b60006135d46135cf84613590565b6133b9565b9050828152602081018484840111156135f0576135ef613354565b5b6135fb848285613405565b509392505050565b600082601f8301126136185761361761324f565b5b81356136288482602086016135c1565b91505092915050565b6000806000806080858703121561364b5761364a612fa4565b5b6000613659878288016131fa565b945050602061366a878288016131fa565b935050604061367b87828801613145565b925050606085013567ffffffffffffffff81111561369c5761369b612fa9565b5b6136a887828801613603565b91505092959194509250565b600080600080604085870312156136ce576136cd612fa4565b5b600085013567ffffffffffffffff8111156136ec576136eb612fa9565b5b6136f88782880161325e565b9450945050602085013567ffffffffffffffff81111561371b5761371a612fa9565b5b6137278782880161325e565b925092505092959194509250565b6000806040838503121561374c5761374b612fa4565b5b600061375a858286016131fa565b925050602061376b858286016131fa565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b60006137bd82613069565b6137c781856137a1565b93506137d7818560208601613085565b6137e0816130b8565b840191505092915050565b60006137f783836137b2565b905092915050565b6000602082019050919050565b600061381782613775565b6138218185613780565b93508360208202850161383385613791565b8060005b8581101561386f578484038952815161385085826137eb565b945061385b836137ff565b925060208a01995050600181019050613837565b50829750879550505050505092915050565b6000602082019050818103600083015261389b818461380c565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806138ea57607f821691505b602082108114156138fe576138fd6138a3565b5b50919050565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b6000613960602c83613074565b915061396b82613904565b604082019050919050565b6000602082019050818103600083015261398f81613953565b9050919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006139f2602183613074565b91506139fd82613996565b604082019050919050565b60006020820190508181036000830152613a21816139e5565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b6000613a84603883613074565b9150613a8f82613a28565b604082019050919050565b60006020820190508181036000830152613ab381613a77565b9050919050565b600081905092915050565b6000613ad18385613aba565b9350613ade838584613405565b82840190509392505050565b6000613af7828486613ac5565b91508190509392505050565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b6000613b5f603183613074565b9150613b6a82613b03565b604082019050919050565b60006020820190508181036000830152613b8e81613b52565b9050919050565b600081905092915050565b50565b6000613bb0600083613b95565b9150613bbb82613ba0565b600082019050919050565b6000613bd182613ba3565b9150819050919050565b7f4661696c656420746f207769746864726177204d617469630000000000000000600082015250565b6000613c11601883613074565b9150613c1c82613bdb565b602082019050919050565b60006020820190508181036000830152613c4081613c04565b9050919050565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b6000613ca3602983613074565b9150613cae82613c47565b604082019050919050565b60006020820190508181036000830152613cd281613c96565b9050919050565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b6000613d35602a83613074565b9150613d4082613cd9565b604082019050919050565b60006020820190508181036000830152613d6481613d28565b9050919050565b7f4f6e6c7920746865206f776e6572206f662074686520646f6d61696e2063616e60008201527f207365742061207265636f726400000000000000000000000000000000000000602082015250565b6000613dc7602d83613074565b9150613dd282613d6b565b604082019050919050565b60006020820190508181036000830152613df681613dba565b9050919050565b7f45524337323155524953746f726167653a2055524920717565727920666f722060008201527f6e6f6e6578697374656e7420746f6b656e000000000000000000000000000000602082015250565b6000613e59603183613074565b9150613e6482613dfd565b604082019050919050565b60006020820190508181036000830152613e8881613e4c565b9050919050565b6000613e9a82613069565b613ea48185613aba565b9350613eb4818560208601613085565b80840191505092915050565b6000613ecc8285613e8f565b9150613ed88284613e8f565b91508190509392505050565b7f4e616d65732063616e2068617665206265747765656e203320616e642031302060008201527f6368617273000000000000000000000000000000000000000000000000000000602082015250565b6000613f40602583613074565b9150613f4b82613ee4565b604082019050919050565b60006020820190508181036000830152613f6f81613f33565b9050919050565b7f4e616d6520697320616c726561647920696e2075736500000000000000000000600082015250565b6000613fac601683613074565b9150613fb782613f76565b602082019050919050565b60006020820190508181036000830152613fdb81613f9f565b9050919050565b7f4e6f7420656e6f756768204d4154494320706169640000000000000000000000600082015250565b6000614018601583613074565b915061402382613fe2565b602082019050919050565b600060208201905081810360008301526140478161400b565b9050919050565b7f2e00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614084600183613aba565b915061408f8261404e565b600182019050919050565b60008190508160005260206000209050919050565b600081546140bc816138d2565b6140c68186613aba565b945060018216600081146140e157600181146140f257614125565b60ff19831686528186019350614125565b6140fb8561409a565b60005b8381101561411d578154818901526001820191506020810190506140fe565b838801955050505b50505092915050565b600061413b828587613ac5565b915061414682614077565b915061415282846140af565b9150819050949350505050565b600061416b82866140af565b91506141778285613e8f565b915061418382846140af565b9150819050949350505050565b7f7b226e616d65223a202200000000000000000000000000000000000000000000600082015250565b60006141c6600a83613aba565b91506141d182614190565b600a82019050919050565b7f222c20226465736372697074696f6e223a20224120646f6d61696e206f6e207460008201527f6865204e696e6a61206e616d652073657276696365222c2022696d616765223a60208201527f2022646174613a696d6167652f7376672b786d6c3b6261736536342c00000000604082015250565b600061425e605c83613aba565b9150614269826141dc565b605c82019050919050565b7f222c226c656e677468223a220000000000000000000000000000000000000000600082015250565b60006142aa600c83613aba565b91506142b582614274565b600c82019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b60006142f6600283613aba565b9150614301826142c0565b600282019050919050565b6000614317826141b9565b91506143238286613e8f565b915061432e82614251565b915061433a8285613e8f565b91506143458261429d565b91506143518284613e8f565b915061435c826142e9565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b600061439f601d83613aba565b91506143aa82614369565b601d82019050919050565b60006143c082614392565b91506143cc8284613e8f565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061444082613124565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561447357614472614406565b5b600182019050919050565b6000604082019050818103600083015261449881856130c9565b905081810360208301526144ac81846130c9565b90509392505050565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b6000614511602c83613074565b915061451c826144b5565b604082019050919050565b6000602082019050818103600083015261454081614504565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006145a3602583613074565b91506145ae82614547565b604082019050919050565b600060208201905081810360008301526145d281614596565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614635602483613074565b9150614640826145d9565b604082019050919050565b6000602082019050818103600083015261466481614628565b9050919050565b600061467682613124565b915061468183613124565b92508282101561469457614693614406565b5b828203905092915050565b60006146aa82613124565b91506146b583613124565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156146ea576146e9614406565b5b828201905092915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061472b601983613074565b9150614736826146f5565b602082019050919050565b6000602082019050818103600083015261475a8161471e565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006147bd603283613074565b91506147c882614761565b604082019050919050565b600060208201905081810360008301526147ec816147b0565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b600061484f602f83613074565b915061485a826147f3565b604082019050919050565b6000602082019050818103600083015261487e81614842565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006148bf82613124565b91506148ca83613124565b9250826148da576148d9614885565b5b828204905092915050565b60006148f082613124565b91506148fb83613124565b92508261490b5761490a614885565b5b828206905092915050565b6000608082019050818103600083015261493081876130c9565b9050818103602083015261494481866130c9565b9050818103604083015261495881856130c9565b905061496760608301846134cd565b95945050505050565b600061497b82613124565b915061498683613124565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156149bf576149be614406565b5b828202905092915050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000614a26602e83613074565b9150614a31826149ca565b604082019050919050565b60006020820190508181036000830152614a5581614a19565b9050919050565b60006060820190508181036000830152614a7681866130c9565b9050614a8560208301856134cd565b8181036040830152614a9781846130c9565b9050949350505050565b600081519050919050565b600082825260208201905092915050565b6000614ac882614aa1565b614ad28185614aac565b9350614ae2818560208601613085565b614aeb816130b8565b840191505092915050565b6000608082019050614b0b60008301876131b9565b614b1860208301866131b9565b614b2560408301856134cd565b8181036060830152614b378184614abd565b905095945050505050565b600081519050614b5181612fda565b92915050565b600060208284031215614b6d57614b6c612fa4565b5b6000614b7b84828501614b42565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614bba602083613074565b9150614bc582614b84565b602082019050919050565b60006020820190508181036000830152614be981614bad565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614c26601c83613074565b9150614c3182614bf0565b602082019050919050565b60006020820190508181036000830152614c5581614c19565b905091905056fe0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d5265676973746572696e672025732e2573206f6e2074686520636f6e7472616374207769746820746f6b656e49442025642d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0a4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220f34ae7380f9822c278ead0324dee89e34ba7d535e8d05183ad425e34b68f48ba64736f6c634300080a0033",
541 | "linkReferences": {},
542 | "deployedLinkReferences": {}
543 | }
544 |
--------------------------------------------------------------------------------